
SIMD(Single Instruction, Multiple Data )は、フリンの分類法における並列コンピューティング(処理)の一種です。SIMDは、複数の処理要素が複数のデータポイントに対して同時に同じ演算を実行するコンピュータを指します。SIMDは内部的に(ハードウェア設計の一部として)実装することも、命令セットアーキテクチャ(ISA)を介して直接アクセスすることも可能ですが、ISAと混同してはいけません。
このようなマシンはデータレベルの並列性を利用しますが、並行性は利用しません。同時(並列)計算はありますが、各ユニットは任意の時点でまったく同じ命令を実行します(ただし、データは異なります)。簡単な例として、多数の数値のペアを加算する場合、すべてのSIMDユニットが加算を実行しますが、それぞれ加算する値のペアが異なります。SIMDは、デジタル画像のコントラスト調整やデジタルオーディオの音量調整などの一般的なタスクに特に適しています。最新の中央処理装置(CPU)設計のほとんどには、マルチメディア使用のパフォーマンスを向上させるためにSIMD命令が含まれています。最近のCPUでは、SIMDユニットはキャッシュ階層とプリフェッチメカニズムと密接に結合されており、大きなブロック操作中のレイテンシを最小限に抑えます。たとえば、AVX-512対応プロセッサは、キャッシュライン全体をプリフェッチして、単一のSIMDサイクルで融合乗算加算演算(FMA)を適用できます。

SIMDは、 Flynnの1972年の分類体系において3つの異なるサブカテゴリに分類され、そのうちの1つが単一命令複数スレッド(SIMT)です。SIMTは、タスクのタイムシェアリング(タイムスライシング)であるソフトウェアスレッドやハードウェアスレッドと混同してはなりません。SIMTは、 ILLIAC IVのように、ハードウェアレベルでの真の同時並列実行です。
SIMDは、 Cray 1に代表され、ダンカンの分類法で明確にされているベクトル処理と混同してはならない。SIMD とベクトルプロセッサの主な違いは、Crayスタイルの命令が存在するかどうかである。SET VECTOR LENGTH
レジスタ内でSIMDが実際に使用された最初の事例として知られているのは、 1958年のTX-2である。TX-2は36ビット演算と、2つの18ビットまたは4つの9ビットのサブワード演算が可能だった。
SIMD命令が初めて商用利用されたのは、1972年に完成したILLIAC IVであった。
1970年代初頭のCDC Star-100やTexas Instruments ASCなどのベクトルスーパーコンピュータは、単一の命令でデータの「ベクトル」を処理できた。ベクトル処理は、1970年代と1980年代にCrayによって特に普及した。ベクトル処理アーキテクチャは現在、SIMDコンピュータとは別個のものと考えられている。Duncanの分類法にはベクトル処理が含まれているが、 Flynnの分類法には含まれていない。これは、Flynnの研究(1966年、1972年)がCray-1(1977年)よりも前に行われたためである。しかし、ベクトルプロセッサの複雑さから、レジスタ内のSIMDとして知られるより単純な構成が生まれた。
現代の SIMD コンピュータの最初の時代は、Thinking Machines Connection Machine CM-1 や CM-2のような大規模並列処理型のスーパーコンピュータによって特徴づけられました。これらのコンピュータには、並列に動作する多数の限定機能プロセッサが搭載されていました。たとえば、Thinking Machines CM-2 の 65,536 個のシングルビットプロセッサはそれぞれ同じ命令を同時に実行し、たとえば、ハイパーキューブ接続ネットワークまたはプロセッサ専用 RAM を使用してオペランドを検索し、一度に 65,536 組のビットを論理的に組み合わせることができました。Intel i860 XPなどの汎用プロセッサに基づく安価なスカラー多重命令多重データ(MIMD) 方式がより強力になり、SIMD への関心が薄れると、スーパーコンピューティングは SIMD 方式から離れました。[ 3 ]
SIMD プロセッサの現在の時代は、スーパーコンピュータ市場ではなくデスクトップコンピュータ市場から生まれた。1990 年代にデスクトッププロセッサがリアルタイム ゲームやオーディオ/ビデオ処理をサポートできるほど強力になると、この種のコンピューティング パワーに対する需要が高まり、マイクロプロセッサ ベンダーは需要を満たすために SIMD に目を向けた。[ 4 ]この復活は、内部で SIMD を大いに活用したDirectXおよび OpenGL シェーダー モデルの台頭とも一致した。グラフィックス API はプログラマにデータ並列プログラミング スタイルを採用するよう促し、間接的にデスクトップ ソフトウェアでの SIMD 採用を加速させた。ヒューレット パッカードは、MPEG デコードを高速化するために、1994 年にPA-RISC 1.1 デスクトップにMultimedia Acceleration eXtensions (MAX) 命令を導入した。 [ 5 ]サン マイクロシステムズは、1995 年にUltraSPARC Iマイクロプロセッサで、命令セット拡張「 VIS 」に SIMD 整数命令を導入した。 MIPSもこれに倣い、同様のMDMXシステムを導入した。
広く普及した最初のデスクトップ SIMD は、1996 年に Intel がx86アーキテクチャにMMX拡張機能を導入したものでした。これにより、 Motorola PowerPCと IBM のPOWERシステムに、はるかに強力なAltiVecシステムの導入が促されました。Intel は 1999 年に、まったく新しいSSEシステムを導入することで対応しました。それ以来、両方のアーキテクチャの SIMD 命令セットにはいくつかの拡張機能があります。高度なベクトル拡張機能 AVX、AVX2、およびAVX-512は Intel によって開発されました。AMD は、現在の製品でAVX、 AVX2、およびAVX-512をサポートしています。 [ 6 ]
SIMDでは、同等のスカラーコードや同等のベクトルコードと比較して、コードサイズが桁違いに増加することは珍しくなく、ベクトルISAでは桁違い以上の効率(命令あたりの作業量)が達成可能です。[ 7 ]
ARMのスケーラブルベクトル拡張は、 Flynnの分類法で「述語付き」(マスク付き) SIMDとして今日ではより一般的に知られている別のアプローチを採用しています。このアプローチはベクトル処理ほどコンパクトではありませんが、述語なしSIMDよりははるかに優れています。詳細な比較例は、ベクトルプロセッサ§ ベクトル命令の例に記載されています。
小規模 (64 ビットまたは 128 ビット) SIMD は、1990 年代初頭に汎用 CPU で普及し、1997 年以降、Alpha用の Motion Video Instructions (MVI) でさらに普及しました。SIMD 命令は、IBMのAltiVecおよびPowerPC用の Signal Processing Engine (SPE) 、Hewlett-Packard (HP) のPA-RISC Multimedia Acceleration eXtensions (MAX)、IntelのMMX および iwMMXt、Streaming SIMD Extensions (SSE)、SSE2 、 SSE3、SSSE3およびSSE4.x、AMDの3DNow!、ARC のARC Video サブシステム、SPARCのVISおよび VIS2、SunのMAJC、ARM のNeonテクノロジー、MIPSのMDMX (MaDMaX) およびMIPS-3Dなど、ほとんどの CPU で、程度の差こそあれ見つけることができます。
IntelのAVX-512 SIMD命令は、一度に512ビットのデータを処理します。
IBM、ソニー、東芝が共同開発したCellプロセッサのシナジスティック処理要素(SPE)の命令セットは、SIMDを多用している。
GPU の中には SIMD ベースであるものもありますが、すべてではありません。AMD の GPU はTeraScale (マイクロアーキテクチャ)以降SIMD ベースであり、この機能は 2020 年代のマイクロアーキテクチャ RDNA および CDNA [ 8 ]にも引き継がれ、その上に単一命令複数スレッド(SIMT)のレイヤーがあります。[ 9 ]一方、Nvidia の CUDA アーキテクチャは SIMT を備えたスカラー コアを使用しています。[ 10 ]
フィリップス(現NXP)は、 Xetalという名称のSIMDプロセッサをいくつか開発した。Xetalは、特に画像処理タスク向けに設計された320個の16ビットプロセッサ素子を備えている。
AppleのM1およびM2チップには、GPUおよびNeural Engineと深く統合されたSIMDユニットが搭載されており、画像フィルタリング、畳み込み、行列乗算に最適化されたApple独自のSIMDパイプラインが使用されています。この統合されたメモリアーキテクチャにより、SIMD命令は共有メモリプール上でより効率的に動作します。(CPU部分は通常のNEONを実装しています。)


SIMD 命令は 3D グラフィックスの処理に広く使用されていますが、SIMD を組み込んだ最新のグラフィックス カードが、このタスクの大部分を CPU から引き継いでいます。一部のシステムには、ベクトル内の要素を再パックするパーミュート関数も含まれており、データ処理や圧縮に特に役立ちます。暗号化にも使用されています。[ 11 ] [ 12 ] [ 13 ] GPU 上での汎用コンピューティング ( GPGPU ) の傾向により、将来的に SIMD の使用がさらに広がる可能性があります。LLVM 、GNU Compiler Collection (GCC)、Intel の ICC などの最近のコンパイラは、積極的な自動ベクトル化オプションを提供しています。開発者は、多くの場合、またはなどのフラグを使用してこれらを有効にできます。これらのフラグは、コンパイラに SIMD 互換性のためにループを再構築するように指示します。-O3-ftree-vectorize
パーソナルコンピュータソフトウェアにおけるSIMDシステムの採用は、当初は多くの問題により緩慢だった。その一つは、初期のSIMD命令セットの多くが、既存の浮動小数点レジスタを再利用するため、システム全体のパフォーマンスを低下させる傾向があったことである。MMXや3DNow!などの他のシステムは、幅広いユーザーにとって関心のないデータ型をサポートしており、 FPUレジスタとMMXレジスタを切り替えるための高コストなコンテキストスイッチング命令を備えていた。また、コンパイラのサポートが不十分な場合も多く、プログラマはアセンブリ言語によるコーディングに頼らざるを得なかった。
x86上の SIMD はゆっくりとしたスタートを切りました。AMDによる3DNow!とIntelによるSSEの導入は多少混乱を招きましたが、今日では (AMD が SSE を採用した後) システムは落ち着いており、新しいコンパイラによって SIMD 対応ソフトウェアが増えるはずです。現在、Intel と AMD はどちらも SIMD 命令を使用する最適化された数学ライブラリを提供しており、 libSIMD、SIMDx86、SLEEFなどのオープンソースの代替ライブラリも登場し始めています ( libmも参照)。[ 14 ]
Apple Computer は、他社より遅れて SIMD 市場に参入したにもかかわらず、ある程度成功を収めました。AltiVecは豊富なシステムを提供し、Motorola、IBM、GNUの高度化するコンパイラを使用してプログラミングできるため、アセンブリ言語によるプログラミングはほとんど必要ありません。さらに、SIMD の恩恵を受けるシステムの多くは、iTunesやQuickTimeのように Apple 自身が提供していました。しかし、2006 年に Apple コンピュータは Intel x86 プロセッサに移行しました。Apple のAPIと開発ツール( Xcode ) は、AltiVec だけでなくSSE2とSSE3もサポートするように変更されました。Apple は IBM とFreescale Semiconductorの PowerPC チップの主要購入者でした。Apple は製品に PowerPC プロセッサを使用しなくなりましたが、AltiVec のさらなる開発は、Freescale と IBM のいくつかの PowerPC およびPower ISA設計で継続されています。
レジスタ内SIMD(SWAR)とは、SIMD命令を直接サポートしないハードウェア上で、汎用レジスタ内でSIMDを実行するために用いられる様々な技術や手法の総称です。これにより、SIMDを直接サポートしないハードウェア上でも、特定のアルゴリズムにおける並列性を活用することが可能になります。
SIMD命令セットの発行元が、ベクトルコードの生成を保証する組み込み関数や特殊データ型(演算子オーバーロード付き)を用いた独自のC言語およびC++言語拡張機能を作成するのは一般的です。Intel、AltiVec、ARM NEONは、自社CPUをターゲットとするコンパイラに広く採用されている拡張機能を提供しています。(より複雑な演算はベクトル演算ライブラリの役割です。)
GNU C コンパイラは、SIMD データ型を定義する方法を提供することで、拡張機能をあらゆるプラットフォームで使用できるユニバーサル インターフェースに抽象化することで、拡張機能をさらに一歩進めています。[ 15 ] LLVM Clangコンパイラも、IR で定義された同様のインターフェースを使用してこの機能を実装しています。[ 16 ] Rust のpacked_simdクレート (および実験的なものstd::simd) はこのインターフェースを使用しており、Swift 2.0+ も同様です。
std::experimental::simdC++には、GCC拡張機能と同様に動作する実験的なインターフェースがあります。LLVMのlibcxxがそれを実装しているようです。GCCとlibstdc++については、GCC拡張機能の上に構築されたラッパーライブラリが利用可能です。[ 17 ]
Microsoft はRyuJIT で.NETに SIMD を追加しました。[ 18 ] NuGet で入手可能なパッケージSystem.Numerics.Vectorは SIMD データ型を実装しています。[ 19 ] Java にも、 OpenJDK 17 のインキュベーター モジュールで利用可能な SIMD 命令用の新しい API が提案されています。 [ 20 ]また、サポートされていない CPU に対しては、単純なループへの安全なフォールバック メカニズムも備えています。
SIMD データ型を提供する代わりに、コンパイラにループを自動ベクトル化するようにヒントを与えることもできます。この場合、データ依存性がないことを前提としたアサーションが必要になる可能性があります。これは SIMD 変数を直接操作するほど柔軟ではありませんが、使いやすくなっています。OpenMP 4.0以降にはヒントがあります。[ 21 ]このOpenMPインターフェースは、 Cilkの[ 22 ]、GCC の[ 23 ]など、さまざまな非標準拡張機能を置き換えました。#pragma omp simd#pragma simd#pragma GCC ivdep
「SIMD everywhere」は、他のプラットフォーム向けにプラットフォーム固有の組み込み関数を実装するC/C++ヘッダーのコレクション(例えば、ARM NEON用のSSE組み込み関数)であり、プラットフォーム固有の組み込み関数、汎用ベクトルインターフェース、およびベクトル化ヒントの使用を含みます。これは、これらの異なるSIMDプログラミングパラダイムを比較するための「ロゼッタストーン」として使用できます。[ 24 ]
別のアプローチはSPMDです。これは、一度に 1 つの要素のみを操作するように見えるプログラムを作成し、コンパイラに SIMD ベクトルの幅に合わせて拡張させるものです。これはグラフィックスシェーダーで使用されているアプローチであり、最近では Intel IPSC などの CPU 指向のツールにも採用されています。[ 25 ]
コンシューマー向けソフトウェアは通常、複数の世代にわたる幅広いCPUで動作することが求められるため、プログラマーが新しいSIMD命令を使用してプログラムの計算性能を向上させる能力が制限される可能性があります。解決策は、古いSIMD技術または新しいSIMD技術を使用する同じコードの複数のバージョンを含め、実行時にユーザーのCPUに最適なものを選択することです(動的ディスパッチ)。解決策には主に2つの方法があります。
アセンブリ言語で手動でコーディングされた FMV は、glibc や libjpeg-turbo などのパフォーマンスが重要なライブラリでよく使用されています。Intel C++ Compiler、GCC 6 以降のGNU Compiler Collection 、clang 7 以降のClangでは、コンパイラが関数の複製と選択を処理するため、よりシンプルなアプローチが可能です。 GCC と clang では、target_clones関数を「クローン」するためにコードに明示的なラベルが必要ですが[ 26 ]、ICC は (コマンドライン オプションで/Qax) 自動的に行います。Rust プログラミング言語も FMV をサポートしています。セットアップは、コードがコンパイルする命令セットを定義するという点で GCC や Clang と似ていますが、クローンはインライン化によって手動で行われます。[ 27 ]
FMV を使用するには GCC と Clang のコード変更が必要となるため、ベンダーはライブラリのマルチバージョン化をより一般的に使用しています。これはコンパイラのスイッチを変更するだけで済むため、より簡単に実現できます。GlibcはLMV をサポートしており、この機能は Intel が支援する Clear Linux プロジェクトで採用されています。[ 28 ]
2013年、ジョン・マカッチャンは、 Dartプログラミング言語用の高性能SIMD命令セットインターフェースを作成し、初めてSIMDの利点をWebプログラムにもたらしたと発表した。インターフェースは2つのタイプで構成されている。[ 29 ]
これらの型のインスタンスは不変であり、最適化されたコードではSIMDレジスタに直接マッピングされます。Dartで表現された演算は通常、オーバーヘッドなしで単一の命令にコンパイルされます。これはCおよびC++の組み込み関数と同様です。4 ×4行列乗算、3D頂点変換、マンデルブロ集合の可視化に関するベンチマークでは、Dartで記述されたスカラーコードと比較して、約400%の高速化が実現されています。
IntelはIDF 2013で、 V8とSpiderMonkeyの両方でMcCutchanの仕様を実装すると発表した。[ 30 ]しかし、2017年までにSIMD.jsはECMAScript標準キューから外され、WebAssemblyで同様のインターフェースを追求することになった。[ 31 ]
SIMD のサポートは、2022 年に完成し、2024 年 12 月に正式版となったWebAssembly 2.0 仕様に追加されました。 [ 32 ] LLVM の自動ベクタリングは、C または C++ を WebAssembly にコンパイルする際に、WebAssembly SIMD をターゲットにして SIMD を自動的に利用することができ、SIMD 組み込み関数も利用可能です。[ 33 ]
汎用コンピューティングにおいて、SIMD専用プロセッサの持続可能な商業的用途を見つけることは、一般的に困難であることが証明されている。
一定の成功を収めているものの一つがGAPPです。これはロッキード・マーティン社が開発し、同社のスピンオフ企業であるテラネックス社が商用化しました。GAPPの最新版は、さまざまなビデオ規格やフレームレート間の変換(NTSCとPAL間、NTSCと高精細テレビ(HDTV)フォーマット間など)、インターレース解除、画像ノイズ低減、適応型ビデオ圧縮、画像強調といったリアルタイムビデオ処理アプリケーションにおいて強力なツールとなっています。
SIMDのより一般的な応用例はビデオゲームに見られます。 1998年以降のほぼすべての最新ビデオゲーム機は、アーキテクチャのどこかにSIMDプロセッサを組み込んでいます。PlayStation 2は、ベクトル浮動小数点演算ユニットの1つが、独自の命令ストリームを実行する自律的なデジタル信号プロセッサ(DSP)として、または通常のCPU命令によって駆動されるコプロセッサとして機能できるという点で特異でした。3Dグラフィックスアプリケーションは、4次元ベクトルの演算に大きく依存するため、SIMD処理に適しています。MicrosoftのDirect3D 9.0は、実行時に独自の数学演算のプロセッサ固有の実装を選択し、SIMD対応命令の使用も行っています。
ベクトル処理を採用した後期のプロセッサとしては、PlayStation 3に搭載されたCellプロセッサが挙げられる。これはIBMが東芝およびソニーと共同開発したもので、複数のSIMDプロセッサ(それぞれ独立したローカルストアを持ち、汎用CPUによって制御される非均一メモリアクセス(NUMA)アーキテクチャ)を使用し、3Dおよびビデオ処理アプリケーションに必要な膨大なデータセットに対応するように設計されている。従来のISAとは異なり、独立したスカラーレジスタを持たず、最初からSIMD方式を採用している点が特徴である。
Ziilabsは、メディアプレーヤーや携帯電話などのモバイルデバイスで使用するためのSIMDタイプのプロセッサを製造した。[ 34 ]
より大規模な商用SIMDプロセッサは、ClearSpeed Technology, Ltd.とStream Processors, Inc.から入手可能です。ClearSpeedのCSX600(2004年)は、それぞれ2つの倍精度浮動小数点演算ユニットを備えた96個のコアを搭載し、CSX700(2008年)は192個のコアを搭載しています。Stream Processorsは、コンピュータアーキテクトのビル・ダリーが率いています。同社のStorm-1プロセッサ(2007年)は、 MIPS CPUによって制御される80個のSIMDコアを搭載しています。
{{cite web}}: CS1 maint: タイトルとしてアーカイブされたコピー (リンク)NVIDIAとAMDの両方で、マトリックス命令はSIMT抽象化モデルを破り、ウェーブフロント全体(NVIDIAでは「ワープ」)にわたって動作します。