Upgrade to Pro — share decks privately, control downloads, hide ads and more …

スーパーコンピュータが組込みシステムに降りてくる!
〜新時代の高性能組込みシステムの
SIMD/ベクトル処理の要点を押さえる

 スーパーコンピュータが組込みシステムに降りてくる!
〜新時代の高性能組込みシステムの
SIMD/ベクトル処理の要点を押さえる

スーパーコンピュータで培われてきた並列計算の技術が組込みシステムに降りてきたのは,今に始まったことではなく,今思い起こせば,1994年発売の初代PlayStationや,2000年発売のPlayStation 2のときにも起こっていたことでした。2021年3月には次期ARMアーキテクチャとなるArmv9アーキテクチャではスーパーコンピュータ富岳で用いられるベクトル命令SVE/SVE2が採用されます。新興のISAであるRISC-Vでもベクタ拡張を搭載したD1 chip搭載のIoTボードが市販され,2021年6月にはIntelがベクタ拡張を搭載したRISC-Vチップを含む高性能RISC-Vチップを作ると発表がありました。SIMDについてはこれに先んじて普及しており,広く普及している現行のArmv8アーキテクチャに搭載されています。Arm MaliやNVIDIA JetsonのようにGPUを搭載したIoTも一般的になってきていますが,これらも基本的にはSIMDアーキテクチャをしています。

このようにハイエンドの組込みシステムで用いられるCPUにSIMD/ベクトル処理機能が搭載されていますが,それらを活用するにはどのようにしたらいいでしょうか? 一般的な答えとしては,スーパーコンピュータで長年培われてきた技術に由来するBLAS/LAPACKという線形代数に基づくライブラリと,それを活用するOSSライブラリを利用しましょう,ということになります。といいますのも,BLAS/LAPACKは,人知のかぎりを尽くしてSIMD/ベクトル処理機能を極限まで活用すべくチューニングされていて,これを超えるようなものを容易に開発することはできない「金字塔」だからです。しかし,このようなライブラリを活用するときっとメモリ・ストレージのサイズがかかるだろうとか,原理や仕組みがわからないと安心して使えないとか,そういった要望をおそらく組込みシステムエンジニアは持つのではないかと予想します。

そこで,本分科会では,SIMD/ベクトル処理を活用する上で基礎となるSIMD(Single Instruction Multiple Data)の考え方と,これを生かすためのメモリ配置,SIMD命令・ベクトル命令活用の要点をレクチャーします。BLAS/LAPACKの活用方法については扱いませんが,BLASのAPIのごく一部を例にして,SIMD/ベクトル処理プログラミングのヒントを読み取ってみたいと思います。

Susumu Yamazaki (ZACKY)

September 03, 2021
Tweet

More Decks by Susumu Yamazaki (ZACKY)

Other Decks in Programming

Transcript

  1. എܠ • 2021೥3݄ൃද ࣍ظARMΞʔΩςΫνϟͱͳΔArmv9ΞʔΩςΫνϟ • εʔύʔίϯϐϡʔλ෋ַͰ༻͍ΒΕΔϕΫτϧ໋ྩSVE/SVE2͕࠾༻ • RISC-V • ϕΫλ֦ுΛ౥ࡌͨ͠D1

    chip౥ࡌͷIoTϘʔυ͕ࢢൢ • 2021೥6݄ ϕΫλ֦ுΛ౥ࡌͨ͠RISC-VνοϓΛؚΉߴੑೳRISC-VνοϓΛIntel͕ ࡞Δͱൃද 3 ©︎ 2021 Susumu Yamazaki
  2. എܠ • SIMD(Single Instruction Multiple Data) ʹ͍ͭͯ͸͜ΕʹઌΜͯ͡ීٴ • ޿͘ීٴ͍ͯ͠ΔݱߦͷArmv8ΞʔΩςΫνϟʹSIMD͕౥ࡌ •

    GPU΋جຊతʹ͸SIMDΞʔΩςΫνϟ • Arm Mali΍NVIDIA JetsonͷΑ͏ʹGPUΛ౥ࡌͨ͠IoT΋Ұൠత 4 ©︎ 2021 Susumu Yamazaki
  3. ϋΠΤϯυͷ૊ࠐΈγεςϜʹ౥ࡌ͞ΕΔSIMD/ϕΫτϧॲཧػೳΛ׆༻͢Δʹ͸ • ͦ͜Ͱɼຊ෼ՊձͰ͸ɼ࣍ͷ͜ͱΛϨΫνϟʔ͠·͢ • SIMDʗϕΫτϧॲཧΛ׆༻͢Δ্ͰجૅͱͳΔSIMD(Single Instruction Multiple Data)ͷߟ͑ํ • ͜ΕΛੜ͔ͨ͢ΊͷϝϞϦ഑ஔ

    • SIMD໋ྩɾϕΫτϧ໋ྩ׆༻ͷཁ఺ • BLASͷAPIͷ͘͝Ұ෦Λྫʹͯ͠ಡΈऔͬͨɼSIMDʗϕΫτϧॲཧϓϩάϥϛϯάͷώϯτ • ٯʹѻΘͳ͍͜ͱ • BLAS/LAPACKͷ׆༻ํ๏ʹ͍ͭͯ 8 ©︎ 2021 Susumu Yamazaki
  4. ฒྻॲཧͷ෼ྨ • SISD(γεσΟ: Single Instruction Single Data: ୯Ұ໋ྩ୯Ұσʔλ): ฒྻͰ͸ͳ͍ •

    SIMD(γϜσΟ: Single Instruction Multiple Data: ୯Ұ໋ྩෳ਺σʔλ) • MISD(ϛεσΟ: Multiple Instruction Single Data: ෳ਺໋ྩ୯Ұσʔλ) • MIMD(ϛϜσΟ: Multiple Instruction Multiple Data: ෳ਺໋ྩෳ਺σʔλ) 12 ©︎ 2021 Susumu Yamazaki
  5. MIMD • MIMD (ϛϜσΟʔɼMultiple Instruction Multiple Data): 
 1ͭ1͕ͭҟͳΔಈ࡞͕Ͱ͖ΔܭࢉϢχοτʹฒྻॲཧ 


    ͤ͞Δํࣜ • ͨͱ͑ΔͳΒɼङΛ͢Δ͍͞ͷङྌݘͷΑ͏ʹɼ֤ʑ͕ ࿈ܞ͠ͳ͕Βݸผͷಈ͖Λ͢Δํࣜ • ϚϧνίΞCPUͱ͍ͬͨͱ͖ʹ͸ɼ1ͭ1ͭͷίΞ͕ಠཱ ͯ͠ݸผͷಈ͖Λ͢Δ͜ͱ͕Ͱ͖Δ • MIMD͸SIMDͱൺ΂ͯฒྻ౓ΛՔ͗ʹ͍͘ • ࢢൢ͞Ε͍ͯΔCPUͰ͸਺ेʙඦ਺ेίΞ͕͍͍ͤͥ • ݚڀஈ֊Ͱ͸ઍݸҎ্ͷίΞΛ࣋ͭ΋ͷ΋͋Δ 13 ©︎ 2021 Susumu Yamazaki
  6. SIMD • SIMD(γϜσΟ, Single Instruction Multiple Data) 
 ಉ͡ಈ࡞Λ͢ΔܭࢉϢχοτʹฒྻॲཧͤ͞Δ ํࣜ

    • ͨͱ͑ΔͳΒా২͑Λͨ͘͞Μͷਓ਺Ͱಉ࣌ʹ ߦ͏Α͏ͳ΋ͷ • CPU ͷ SIMD ໋ྩ΍ϕΫλ໋ྩɼGPUͰ࠾༻ • SIMDํࣜͩͱฒྻ౓Λ্͛΍͘͢ɼ1000Ҏ্ ͷฒྻ౓Λ࣋ͭGPU͕ࢢൢ͞Ε͍ͯΔ 14 ©︎ 2021 Susumu Yamazaki
  7. CPUͷSIMD໋ྩ • ݻఆ௕ͷϏοτ෯ͷSIMDϨδελͰԋࢉΛߦ͏ • Intel SSEͳΒ͹128Ϗοτ • Intel AVX /

    AVX2ͳΒ͹256Ϗοτ • Intel AVX-512ͳΒ͹512Ϗοτ • ARM NEON ͳΒ͹128Ϗοτ(ARMv8ͷ৔߹) • SIMDϨδελΛ۠੾ͬͯ࢖༻͢Δ • ੔਺ͳΒ͹{ූ߸෇͖/ͳ͠},{8/16/32/64Ϗοτ} • ුಈখ਺఺਺ͳΒ͹൒ਫ਼౓(16Ϗοτ)(ARM NEONͷΈ)/୯ਫ਼౓(32 Ϗοτ)/ഒਫ਼౓(64Ϗοτ) • ར఺: ࣮ݱ͕༰қ • ͨͱ͑͹੔਺ͷՃݮࢉ໋ྩͰ͋Ε͹ɼ۠੾ͬͨϏοτҐஔͰՃࢉ 
 ճ࿏ͷΩϟϦʔʗϘϩʔΛ఻೻ͤ͞ͳ͍Α͏ʹ͢Ε͹ɼ࣮ݱͰ͖Δ • ܽ఺: • ΫϩοΫप೾਺ͷ޲্ͷ৔߹ͱҟͳΓɼSIMD໋ྩΛར༻͠ͳ͍ͱ ੑೳ͸্͕Βͳ͍ͷͰΞηϯϒϦϓϩάϥϛϯά΋͘͠͸SIMD໋ ྩͷίʔυੜ੒ʹରԠͨ͠ίϯύΠϥ͕ඞਢ • SIMDϨδελͷϏοτ෯͕มΘΔͱػցޠ໋ྩͷޓ׵ੑ͕ͳ͍ͷ ͰɼϏοτ෯Λม͑Δ࣌ʹϓϩάϥϛϯά΍ίϯύΠϧΛ͠ͳ͓͢ ඞཁ͕͋Δ • ࠷ۙͷClangͱGCC͸ auto vectorization ͕ৗ࣌༗ޮͱͳ͓ͬͯΓɼɹ ϧʔϓʹରͯࣗ͠ಈͰSIMD໋ྩΛ࢖͏Α͏ʹίʔυੜ੒ͯ͘͠ΕΔ 15 ©︎ 2021 Susumu Yamazaki
  8. ϕΫτϧ໋ྩ • ϕΫτϧ໋ྩ΋ฒྻॲཧͷ෼ྨͩͱ SIMDʹ۠෼͞ΕΔ • SIMD໋ྩͷܽ఺: • SIMDϨδελͷϏοτ෯͕มΘΔͱ ػցޠ໋ྩͷޓ׵ੑ͕ͳ͍ͷͰɼ 


    Ϗοτ෯Λม͑Δ࣌ʹϓϩάϥϛϯά ΍ίϯύΠϧΛ͠ͳ͓͢ඞཁ͕͋Δ • ͜Εʹର͠ϕΫτϧ໋ྩͰ͸ • ϕΫτϧϨδελ෯͸CPUʹΑͬͯ ҟͳΔ͕ɼͦΕʹ߹Θͤͯϧʔϓճ਺ ͳͲͷύϥϝʔλΛઃఆ͢Δઐ༻໋ྩ ͕ଘࡏ͢Δ • ͦͷͨΊϕΫτϧϨδελ෯͕มΘͬ ͯ΋ɼϓϩάϥϛϯά΍ίϯύΠϧΛ ͠ͳ͓͢ඞཁ͸ͳ͍ 16 ©︎ 2021 Susumu Yamazaki
  9. αϯϓϧϓϩάϥϜ࡞ͬͯΈ·ͨ͠ • https://github.com/zacky1972/simd_sample • ϞϊΫϩԽͷը૾ϑΟϧλΛ୊ࡐʹ • 8Ϗοτූ߸ͳ͠੔਺→32Ϗοτූ߸ͳ͠੔਺→32Ϗοτුಈখ਺఺਺ 
 →{R, G,

    B} <= 0.299 * r + 0.587 * g + 0.114 * bɹ 
 →খ਺఺ҎԼ࢛ࣺޒೖ→32Ϗοτූ߸ͳ͠੔਺→8Ϗοτූ߸ͳ͠੔਺ɹ • CݴޠͰॻ͍ͨ৔߹ (2छྨ: ޙड़) 
 Auto-vectorizationͷͨΊϧʔϓͰSIMDίʔυΛੜ੒ • Intrinsic (SIMD໋ྩΛCͰهड़͢Δํ๏ͷ1ͭ)Ͱॻ͍ͨ৔߹ • Intel Core i5 / AVX2 • ARMv8 / NEON • Cݴޠ+Auto-vectorizationʹൺ΂ͯSIMD໋ྩΛखͰهड़ͯ͠࠷దԽΛਤΔͱ 
 2ʙ5ഒͷߴ଎ԽޮՌ͕͋Δ • ͔͠΋SIMD໋ྩͷهड़ʹ͸·ͩ࠷దԽͷ༨஍͕͋Γͦ͏ͳײ৮͕͋Δ 23 ©︎ 2021 Susumu Yamazaki
  10. Array of Structures (AoS) • ߏ଄ମͷ഑ྻ • AoS͸SIMDԽ͠ʹ͍͘ • ඈͼඈͼʹࢀর͢Δඞཁ͕͋Δ

    • RGB 8Ϗοτͣͭͩͬͨ৔߹ʹ͸ɼ 
 3όΠτඈ͹͠͠ͳ͕Βr, g, bΛϩʔυͯ͠ 
 ϞϊΫϩԽͷ܎਺Λ͔͚ͯ΍Δඞཁ͕͋Δ • ͨͩ͠ NEON ʹ͸ͦͷͨΊͷศརͳϩʔυɾετΞ໋ ྩ͕උΘ͍ͬͯΔʂ • ͜ͷ৔߹ͩͱ3όΠτͣͭಡΈඈ͹ͯ͠SIMDϨδελ ʹ֨ೲ͍ͯ͘͠ϩʔυ໋ྩ ld3q ͕༻ҙ͞Ε͍ͯΔ 30 ©︎ 2021 Susumu Yamazaki
  11. Structure of Arrays (SoA) • ഑ྻͷߏ଄ମ • AoSΑΓ΋SoAͷํ͕SIMDԽ͠΍͍͢ʂ • 8Ϗοτ഑ྻͷ஋Λ

    
 SSEɾNEONͷ৔߹128Ϗοτ(16ݸ෼)ͣͭ 
 AVX2ͷ৔߹256Ϗοτ(32ݸ෼)ͣͭ 
 AVX-512ͷ৔߹512Ϗοτ(64ݸ෼)ͣͭ 
 ·ͱΊͯॲཧ͢Δܗʹ͠΍͍͢ 31 ©︎ 2021 Susumu Yamazaki
  12. ϕϯνϚʔΫ݁ՌΛ΋͏Ұ౓ݟͯΈΑ͏ • https://github.com/zacky1972/simd_sample • Intel / AVX2 ͩͱ AoSΑΓSoA͕2ഒۙ͘଎͍ •

    SoAͷํ͕SIMDԽ͠΍͍͢ͱ͍͏ఆੴ௨Γ • ARMv8 / NEONͩͱඍົʹAoSͷํ͕଎͍ • NEONʹ༻ҙ͞Ε͍ͯΔ3όΠτඈ͹͠ͷ 
 ϩʔυɾετΞ໋ྩͷޮՌ͔ʁ • ߏ଄ମͷαΠζ͕5όΠτҎ্ʹͳΔͱରԠ͢Δ ໋ྩ͕ͳ͘ͳΔͷͰɼ͓ͦΒ͘஗͘ͳΔͷͰ͸ʁ 32 ©︎ 2021 Susumu Yamazaki
  13. SIMD໋ྩɾϕΫτϧ໋ྩ׆༻ͷཁ఺ • ϞϊΫϩԽͷ৔߹ͷྲྀΕ(͜ΕΒ1ͭ1ͭͷखॱ͸ఆੴύλʔϯʹͳΓͦ͏) 1. ϩʔυ 2. 8Ϗοτ͔Β16Ϗοτʹ֦ுͯ͠ԼҐͱ্Ґʹ෼ׂ 3. 16Ϗοτ͔Β32Ϗοτʹ֦ுͯ͠ԼҐͱ্Ґʹ෼ׂ 4.

    32Ϗοτ੔਺͔Β32Ϗοτුಈখ਺఺਺ʹม׵ 5. ੵ→ੵ࿨→ੵ࿨ 6. 32Ϗοτුಈখ਺఺਺Λ࢛ࣺޒೖͯ͠32Ϗοτ੔਺ʹม׵ 7. 32Ϗοτ͔Β16Ϗοτʹॖখͭͭ͠ԼҐͱ্ҐΛ౷߹ 8. 16Ϗοτ͔Β8Ϗοτʹॖখͭͭ͠ԼҐͱ্ҐΛ౷߹ 9. ετΞ • CPUͷSIMDϨδελ਺Λ௒ա͠ͳ͍Α͏ʹεέδϡʔϦϯά͢Δ • ֦ுͯ͠ԼҐͱ্Ґʹ෼ׂ͢Δࡍʹɼ্ҐͷޙଓͷܭࢉΛޙճ͠ʹ͢Δ • R, GͷॲཧΛઌʹ΍ͬͯɼੵ→ੵ࿨ͯ͠SIMDϨδελΛ·ͱΊͨޙ B ͷॲཧΛߦͳͬͯੵ࿨͢Δ • ม਺ʹܕΛ໌ه͢ΔͱΘ͔Γ΍͍͢ (ϋϯΨϦΞϯه๏తͳΞϓϩʔν) • ྫ: • float32x4_t f32x4_pixel_r; • uint8x16_t u16x8_pixel_b; • NEON͸໋໊نଇ͕Θ͔Γ΍͘͢ɼ 
 ෳࡶͳIntel SSE/AVX ΑΓ΋ϓϩάϥϛϯά͠΍͍͢ 35 ©︎ 2021 Susumu Yamazaki
  14. OpenBLAS • https://github.com/xianyi/OpenBLAS • BLAS: جຊઢܗ୅਺αϒϓϩάϥϜ • OpenBLAS͸࠷దԽ͞ΕͨBLASͷϥΠϒϥϦͰBSDϥΠηϯεͰ 
 ެ։͞Ε͍ͯΔ΋ͷ

    • ࢖͍উखΑΓεϐʔυΛ௥ٻͯ͠API͕ઃܭ͞Ε͍ͯΔ • ͦΕͰ͍ͯ൚༻ੑ͕͋ΔΑ͏ͳઈົ͕͋͞Δ • ͨͱ͑͹GEMM(ߦྻͱߦྻͷੵ) • σʔλܕʹ߹Θͤͯ࠷దԽ͞Ε͍ͯΔ • SGEMM(୯ਫ਼౓൛) • DGEMM(ഒਫ਼౓൛) • CGEMM(ෳૉ਺୯ਫ਼౓൛) • ZGEMM(ෳૉ਺ഒਫ਼౓൛) • ࣍ͷܭࢉΛಉ࣌ʹ࣮ߦ͢Δ͜ͱͰɼେҬతʹ࠷దԽͰ͖Δ • ߦྻͷ৐ࢉ • ߦྻͷసஔ • ߦྻͷεΧϥʔഒ • ߦྻͷՃࢉ 37 ©︎ 2021 Susumu Yamazaki BLAS (Basic Linear Algebra Subprograms) https://www.netlib.org/blas/
  15. OpenBLAS • ΞηϯϒϦίʔυྫ • https://github.com/xianyi/OpenBLAS/ blob/develop/kernel/arm64/ dgemm_kernel_4x4.S • https://github.com/xianyi/OpenBLAS/ blob/develop/kernel/arm64/

    dgemm_kernel_4x8.S • https://github.com/xianyi/OpenBLAS/ blob/develop/kernel/arm64/ dgemm_kernel_8x4.S • ԋࢉΧʔωϧ͕CPUΞʔΩςΫνϟ΍ αΠζͰࡉ͔͘৔߹෼͚͞Ε͍ͯΔ • ϚΫϩ౳Λఆٛ͢Δ͜ͱͰಉ͡Α͏ͳ ίʔυྻΛ޼Έʹ࠶ར༻͍ͯ͠Δ • ಺ଆϧʔϓΛల։ͯ͠଎౓Λ޲্ͤ͞Δ Α͏ʹ͍ͯ͠Δ 38 ©︎ 2021 Susumu Yamazaki
  16. • SIMD͸ಉ͡ಈ࡞Λ͢ΔܭࢉϢχοτʹฒྻॲཧͤ͞Δํࣜ • CPUͷSIMD໋ྩɼϕΫτϧ໋ྩɼGPU͕SIMDʹ֘౰ • CPUͷSIMD໋ྩ͸ݻఆ௕ͷϏοτ෯ͷSIMDϨδελͰԋࢉΛߦ͏ • SIMDϨδελͷϏοτ෯͕มΘΔͱػցޠ໋ྩͷޓ׵ੑ͕ͳ͍ • SIMD໋ྩͷϏοτ෯Λม͑Δ࣌ʹϓϩάϥϛϯά΍ίϯύΠϧΛ͠ͳ͓͢

    ඞཁ͕͋Δ • ϕΫτϧ໋ྩͰ͸ϕΫτϧϨδελ෯͕มΘͬͯ΋ɼϓϩάϥϛϯά΍ 
 ίϯύΠϧΛ͠ͳ͓͢ඞཁ͸ͳ͍ • Cݴޠ+Auto-vectorizationʹൺ΂ͯSIMD໋ྩΛखͰهड़ͯ͠࠷దԽΛਤΔ ͱ2ʙ5ഒͷߴ଎ԽޮՌ͕͋Δ • Auto-vectorizationΛ࢖͏ൣғͰ͸AoS(ߏ଄ମͷ഑ྻ)ΑΓ΋ 
 SoA(഑ྻͷߏ଄ମ)ͷελΠϧʹϝϞϦ഑ஔͨ͠ํ͕ແ೉ͦ͏ • ఆੴύλʔϯΛϚΫϩԽ͢Δͱྑͦ͞͏ • CPUͷSIMD/ϕΫτϧϨδελ਺Λ௒ա͠ͳ͍Α͏εέδϡʔϦϯά͢Δ • ม਺ʹܕΛ໌ه͢ΔͱΘ͔Γ΍͍͢ (ϋϯΨϦΞϯه๏తͳΞϓϩʔν) • NEON͸໋໊نଇ͕Θ͔Γ΍͘͢ɼෳࡶͳIntel SSE/AVX ΑΓ΋ 
 ϓϩάϥϛϯά͠΍͍͢ • ࢖͍উखΑΓεϐʔυΛ௥ٻ͠ɼͦΕͰ͍ͯ൚༻ੑ͕͋ΔΑ͏ͳઈົ͕͞ ͋Δײ͡ͰAPIΛઃܭ͢Δ • ԋࢉΧʔωϧΛCPUΞʔΩςΫνϟ΍αΠζͰࡉ͔͘৔߹෼͚͢Δ • ϚΫϩ౳Λఆٛ͢Δ͜ͱͰಉ͡Α͏ͳίʔυྻΛ࠶ར༻͢Δ • ಺ଆϧʔϓΛల։ͯ͠଎౓Λ޲্ͤ͞Δ ·ͱΊ 40 ©︎ 2021 Susumu Yamazaki