SIMD

**単一命令・複数データ**（、**SIMD**）とは、コンピューターにおける並列計算方式の一つであり、単一の命令を同時に複数のデータ要素へ適用する構造を指す。

1966年にMichael J. Flynnが提唱した計算機アーキテクチャの分類（フリンの分類の分類）に含まれる。主に数値演算、画像処理、信号処理など、同一の演算を大量のデータに対して実行する用途で用いられ、ベクトル計算機やCPUの命令拡張、GPUなどに実装されている。

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

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

:
\left\{
\begin{array}{l}
c_x \leftarrow a_x + b_x
\\
c_y \leftarrow a_y + b_y
\\
c_z \leftarrow a_z + b_z
\\
c_w \leftarrow a_w + b_w
\end{array}
\right.


ここで、それぞれの成分を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レジスタは使えない。このような演算内容やプロセッサに合わせた最適化をコンパイラが行ってくれることも多い。

## 例
### マイクロプロセッサ
#### 命令拡張
* x86のMMX・3DNow!・ストリーミングSIMD拡張命令 (SSE) 
* x64のAdvanced Vector Extensions (AVX), Advanced Matrix Extensions (AMX)
* ARMのAdvanced SIMD (NEON), Scalable Vector Extension (SVE), SVE2, Scalable Matrix Extension (SME)
* RISC-Vのベクトル拡張（Vector Extension）
* PowerPCのAltiVec (VMX)
* SPARCのVIS (:en:Visual Instruction Set)
* MIPSのMIPS-3D (:en:MIPS-3D)・MDMX (:en:MDMX)
* PA-RISCの MAX (:en:Multimedia Acceleration eXtensions)
* Emotion EngineのCPUコア

#### 演算装置
演算装置自体がSIMD型のもの
* Cell Broadband Engine#Synergistic Processor Element

### GPU
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の併用が始まっている。
* NVIDIA GeForce、NVIDIA Quadro、NVIDIA Teslaシリーズなど
: NVIDIA製GPUでは32個のハードウェアスレッド集合を*Warp*と呼ぶ。
* AMD Radeon、AMD FireProシリーズなど
: AMD製GPUでは64個のハードウェアスレッド集合を*Wavefront*と呼ぶ。

* のPowerVR
: PowerVR Series5では4-way、PowerVR Series6では16-wayのベクタユニット

### 物理演算プロセッサ
3Dゲームに必要な物理演算を高速化するため、SIMDを利用。
*PhysX（用のチップ）

### 汎用アクセラレータ
PCI Express接続の汎用SIMDアクセラレータ。倍精度の行列演算を高速に行う目的で、ワークステーション、スーパーコンピュータなどに搭載される。
*CSX600 - クリアスピードによるメニーコアSIMD演算ユニット
*SX-Aurora TSUBASA Vector Engine - NECのスパコンSX-Aurora TSUBASA搭載の演算ユニットをバラ売りしたもの。8コア、最大2.45TFLOPS

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

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

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

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

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

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

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

## 脚注
### 注釈

### 出典

## 関連項目
* マルチプロセッシング
* ベクトル計算機
* フリンの分類
* ベクトル化
* Single Instruction, Multiple Threads (SIMT)