single instruction, multiple data(シングルインストラクション・マルチプルデータ、SIMD[注釈 1][注釈 2])とはコンピューター演算処理に関するフリンの分類のひとつで、1つの命令を同時に複数のデータに適用する並列化の形態を指す[5]。この手法にもとづく演算をベクトル演算 (vector operation) と呼ぶこともある。通例、SIMD命令により同時処理するのに適したデータ構造あるいはデータ型を利用するため、命令実行の前に処理対象のデータ列はいったん結合(パック)され、処理完了後に分解(アンパック)される。結合されたデータはpacked data(パックデータ、パックトデータ)と呼ばれる。

SIMDの概念図
PU = 処理装置 (processing unit)

解説

編集

同一の演算を繰り返すような操作をスカラー計算機のように逐次的に行なうのではなく、一度に行なうものである。

例えば、4次元ベクトル同士の加算を実行する場合、X, Y, Z, Wの成分ごとに加算処理を行なう。

 

ここで、それぞれの成分を32ビットの単精度浮動小数点数で表すとする。32ビットのレジスタ幅を持ち、1命令で32ビットのデータを1組だけ処理できるプロセッサの場合、成分ごとの加算処理すなわち4回の加算命令を逐次実行する必要がある。一方、128ビットのレジスタ幅を持ち、1命令で32ビットのデータ4組を同時に処理できるSIMD命令セットをサポートするプロセッサの場合、1回の命令で全成分をまとめて演算することができ、処理にかかる理論上の消費サイクル数は1/4になる。多くの場合、128ビットを使い切るデータはあまりなく、一般に128ビットを2分割し64ビット×2として使ったり、4分割し32ビット×4として使ったり、8分割し16ビット×8として使ったり、16分割し8ビット×16として使ったりするが、結局それぞれ1回のサイクルで2倍、4倍、8倍、16倍のデータ処理が可能になり、結果として相対的に低いクロック周波数でも高い性能を引き出しやすい。

例えば音声データ全体の音量を倍にしたいとする。デジタルデータではある瞬間の音量が数値として記録されているので、全ての値を倍にすればよい。このように大量のデータに同じ処理を施すときに性能を発揮するため、一般にはマルチメディアの処理に向いているとされる。

SIMD型で、複数の演算装置を並列に使用する計算を初期に試みたコンピュータとしては、ILLIAC IVがある。これに対し、Cray-1のような典型的なベクトル型スーパーコンピュータでは並列に計算するのではなく、パイプライン処理により1個の演算装置を休ませることなく計算させ続ける。ただしベクトル演算という用語は、広義には1命令で複数の要素を計算させるものについて、同時(並列)に計算するものも、パイプラインで計算するものも指すが、ベクトル計算機と言った場合は主として、20世紀のスーパーコンピュータに多く採用されていたパイプライン型を指すことが多い。

他の技術と同じく1990年代後半からパーソナルコンピュータCPU/GPUゲーム機等にも応用された。

なお、SIMD命令を使ったとしても、プロセッサの命令実装形態によっては演算性能が向上しないケースもある。例えば256ビットSIMD命令に対応したプロセッサであっても、256ビット幅の命令を1サイクルで実行できるとは限らず、128ビットの演算器を使って2サイクルで実行する実装になっていることもある。

全ての処理をSIMDで行なえないこともないが、32ビット幅で十分な整数スカラー演算や論理演算の場合、本数の多い従来の汎用レジスタを有効利用するため、SIMDユニットは使わず通常のALUを使うことが多い。また、コンペア・アンド・スワップのような特殊命令は汎用レジスタとメモリの間でデータ交換をするため、SIMDレジスタは使えない。このような演算内容やプロセッサに合わせた最適化をコンパイラが行なってくれることも多い。

マイクロプロセッサ

編集

命令拡張

編集

演算装置

編集

演算装置自体がSIMD型のもの

GPUはSIMD型がほとんどである。ただし、GPGPU対応が進むにつれて、1プロセッサで複数のデータを扱うSIMDだけではなく、複数のプロセッサを用いて実現されるハードウェアマルチスレッドに対して同一の命令を発行することで複数のデータを同時に処理するSIMT英語版の併用が主流となっている。

もともとGPUはXYZW/RGBA(各成分は32ビット単精度浮動小数点数)を同時に演算する128ビットの4-way SIMDが主流だったが、1サイクルで1回の単精度浮動小数点数もしくは32ビット整数の融合積和演算 (FMA) を行なうスカラー型プロセッサを複数束ねるSIMTが主流となった。しかしその後、単精度演算器にて半精度浮動小数点数演算を2回行なう2-way SIMDや、8ビット整数演算を4回行なう4-way SIMDをサポートするGPUも出現し、SIMDとSIMTの併用が始まっている[10]

NVIDIA製GPUでは32個のハードウェアスレッド集合をWarpと呼ぶ。
AMD製GPUでは64個のハードウェアスレッド集合をWavefrontと呼ぶ。
PowerVR Series5では4-way、PowerVR Series6では16-wayのベクタユニット[11]

物理演算プロセッサ

編集

3Dゲームに必要な物理演算を高速化するため、SIMDを利用。

  • PhysX(用のチップ)

汎用アクセラレータ

編集

PCI Express接続の汎用SIMDアクセラレータ。倍精度行列演算を高速に行う目的で、ワークステーションスーパーコンピュータなどに搭載される。

  • CSX600 - クリアスピードによるメニーコアSIMD演算ユニット
  • SX-Aurora TSUBASA Vector Engine - NECのスパコンSX-Aurora TSUBASA搭載の演算ユニットをバラ売りしたもの。8コア、最大2.45TFLOPS[12]

コンパイラサポート

編集

SIMD命令を利用するには、各プロセッサの固有命令をアセンブラで直接記述するほか、高水準言語のコンパイラに実装されている組み込み関数英語版 (intrinsics/intrinsic functions) を利用する方法もある。通例C言語/C++コンパイラには各プロセッサ固有の組み込み関数を定義したヘッダーファイルが用意されており、組み込み関数を呼び出すことで、アセンブラを使用することなく対応するSIMD命令を利用したソースコードを記述することができる。ただしSIMD命令セットおよび組み込み関数はプロセッサによって異なるため、このように手動でベクトル化するとソースコードの移植性が低下するという問題がある。また、本来のアルゴリズムとは関係のない下位レベルのコードを記述しなければならないため、メンテナンス性も低下する。

コンパイラの中には、SIMD命令による自動ベクトル化に対応しているものもある。自動ベクトル化はコンパイラ最適化の一種であり、特定のデータ型の連続したメモリ領域に対する同一の演算の繰り返しなど、特定のパターンに合致する処理を、SIMD命令を使ったベクトル演算に置き換えて高速化する[13][14][15]。自動ベクトル化は手動ベクトル化と比較してきめ細やかな制御は難しく、高速化の度合いはコンパイラの解析能力に左右されるが、ソースコードの移植性やメンテナンス性を維持したまま高速化できるというメリットもある。Clang/LLVMのように、コンパイラ最適化のヒントとしてベクトル幅などを固有のプラグマ指令で指定できるものもある。

OpenMP 4.0ではSIMDベクトル化のプラグマ指令が導入された[16]

JavaではHotSpot Server VM用のHotSpot C2 Compilerがx86/x64/AArch64の自動ベクトル化に対応している[17][18]。Java 16以降は実験的機能モジュール(incubator module)のひとつjdk.incubator.vector[19]の初期版としてVector APIが追加されており[20]、バージョンアップのたびに段階的に機能が追加されている[21]

.NETおよび.NET Framework 4.6以降の64ビット版実行時コンパイラ (RyuJIT) は、System.Numerics名前空間に含まれるSIMD対応型を使って記述されたマネージコードを、SIMD命令で並列化されたネイティブ機械語コードにJITコンパイルすることができる[22]

WebAssemblyでは、128ビットのSIMD命令があり、Chrome 91、Firefox 89、Safari 16.4などで実装されている[23]

ビット演算

編集

ビット演算 (bitwise operation) の命令は、複数のビットを同時に処理することのできる並列性を持つため、広義のSIMDとして並列計算に利用されることもある。

脚注

編集

注釈

編集
  1. ^ 英語では「シムディー」("sim-dee") のように読まれる[1]。日本では「シムド」と呼ぶことがある。
  2. ^ "single instruction stream, multiple data stream" とする資料もある[2][3][4]

出典

編集
  1. ^ SIMD - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
  2. ^ P.HAYES, JOHN (1978,1979). Computer Architecture and Organization. McGRAW-HILL INTERNATIONAL BOOK COMPANY. p. 211. ISBN 0-07-027363-4 
  3. ^ 6 群「コンピュータ - 基礎理論とハードウェア」 - 5 編「コンピュータアーキテクチャ(II) 先進的」 - 4 章「ベクトルコンピュータ」 | 電子情報通信学会「知識ベース」
  4. ^ David A. Patterson and John L. Hennessy (2007). Computer Organization and Design: The Hardware/Software Interface. Morgan Kaufmann Publishers. p. 596. ISBN 978-0-12-370606-5 
  5. ^ SIMD(Single Instruction/Multiple Data)とは - IT用語辞典 e-Words
  6. ^ Arm C Language Extensions Release ACLE Q4 2019 - Advanced SIMD (Neon) intrinsics | Arm Developer
  7. ^ Scalable Vector Extension (SVE) | Arm Developer
  8. ^ Arm、10年ぶりの新アーキテクチャ「Armv9」。富岳のSVE改良版やコンフィデンシャルコンピューティング機能追加”. PC Watch. 株式会社インプレス (2021年3月31日). 2021年12月30日閲覧。
  9. ^ riscv-v-spec/v-spec.adoc at master · riscv/riscv-v-spec”. 2024年6月21日閲覧。
  10. ^ 【後藤弘茂のWeekly海外ニュース】NVIDIA次世代SoC「Xavier」は進化版DenverとVoltaを搭載 - PC Watch
  11. ^ 【後藤弘茂のWeekly海外ニュース】 スマートフォンのグラフィックスを加速する「PowerVR Series6 Rogue」”. PC Watch. 株式会社インプレス (2014年3月19日). 2021年12月29日閲覧。
  12. ^ NEC SX-Aurora TSUBASA Vector Engineの取り扱いを開始
  13. ^ Auto-Vectorizer in Visual Studio 2012 – Overview – Parallel Programming in Native Code
  14. ^ インテル® C++ コンパイラーのベクトル化ガイド - Compiler_AutoVectorization_Guide.pdf
  15. ^ Auto-Vectorization in LLVM — LLVM git documentation
  16. ^ OpenMP 4.0 を使用してプログラムで SIMD を有効にする | iSUS
  17. ^ BUD17-117 Auto Vectorization Support in OpenJDK 9 AArch64 Hotspot C2 Compiler | Linaro
  18. ^ Vectorization in HotSpot JVM | Oracle
  19. ^ jdk.incubator.vector (Java SE 16 & JDK 16)
  20. ^ JEP 338: Vector API (Incubator)”. openjdk.org. 2024年9月8日閲覧。
  21. ^ Java Vector API on AArch64 - High Performance Computing (HPC) blog - Arm Community blogs - Arm Community
  22. ^ .NET における数値 | Microsoft Docs
  23. ^ Using SIMD with WebAssembly — Emscripten 3.1.61-git (dev) documentation”. emscripten.org. 2024年6月1日閲覧。

関連項目

編集