ストリーミングSIMD拡張命令

ストリーミングSIMD拡張命令（英: Streaming SIMD Extensions、略称:SSE）は、インテルが開発したCPUのSIMD拡張命令セット、およびその拡張版の総称である。 SSEは、x86アーキテクチャに8本の128ビットレジスタを新設し、浮動小数点演算のSIMD処理を実現したものである。AMDのK6-2に実装されたSIMD拡張命令3DNow!に対抗する形でPentium IIIから実装された。4個の32ビット単精度浮動小数点データを一本のレジスタに格納し、同一の命令を一括処理することができる。拡張命令であるため、その機能を使用するためにはSSEに対応したソースコードを作成し、プログラムをコンパイルする必要がある。 Core Duoまでのインテル製CPU、K8までのAMD製CPUでは、64ビット幅の演算器を用いて128ビット演算命令を2クロックかけて実行するという実装であったため、128ビット演算命令を用いても実質的なスループットはクロックあたり64ビットであった。そのため従来から存在するMMX命令やAMDの3DNow!命令に対する性能面でのアドバンテージは128ビット幅のレジスタを使えるという点以外では小さく、むしろ並列度が上がった分だけ最適化も煩雑になるという欠点が目立った。また当時のRISC系CPUに搭載されているSIMD命令では128ビット演算命令を1クロックで実行できるものがあり、これらに対する性能的なディスアドバンテージは小さくなかった。最終的にはCoreマイクロアーキテクチャ/AMD K10より128ビット演算命令も1クロック処理が可能な形態へと改良され、SSE命令の実用性は大幅に向上した。 元々はインターネット・ストリーミングSIMD拡張命令（英: Internet Streaming SIMD Extensions、ISSE）と呼ばれていたが 、命令内容そのものはインターネットとは直接関係が無くマーケティング的な要素が強かったため、現在ではインターネットの文言が外され単にSSEと呼ばれるようになっている。 SSEの機能を強化したものにSSE2やSSE3、SSSE3（Supplemental/補足的なSSE3）、SSE4がある。また、SSEは他社製品にも採用されている。 Pentium IIIにはじめて実装された。追加された命令数は70。Pentium IIIの開発コードネームがKatmaiであったことから、KNI (Katmai New Instructions) やMMX2 とも呼ばれていた。廉価製品のCeleronにおいても、その第三世代製品 Coppermine-128k よりSSEに対応している。 AMDによるSIMD拡張命令セット3DNow! Professionalは、SSEと互換性がある。 SSE2は従来のSSEに144個の新たな命令が加えられた。具体的には64ビットの倍精度浮動小数点演算のサポートおよびMMXを128ビット幅に拡張する整数演算命令の追加、キャッシュの制御機能の強化がなされた。 SSE2はPentium 4で初めて実装された。AMDのAMD64アーキテクチャでは、浮動小数点演算に従来のx87命令ではなくSSE/SSE2のスカラ演算命令を用いることを標準としたため、拡張命令ではなく基本命令としてSSE、SSE2が取り込まれている。 SSE3はSSE2に13個の新たな命令が加えられた。具体的にはメモリアクセスおよび複素数計算の高速化、仮想CPUのスレッドの動作制御などの機能が搭載され、主に動画圧縮の処理が向上した。 SSE3の名称が発表される前はPNI (Prescott New Instructions) と呼ばれていた。Pentium 4のPrescottコア（2004年 -）で初めて実装された。 SSSE3 (Supplemental SSE3) はSSE3に32個の新たな命令が加えられた。 CoreマイクロアーキテクチャベースのマイクロプロセッサIntel Core 2 (Conroe) / Intel Xeon (Woodcrest) で初めて実装された。 SSSE3と名付けられる前はMNI (Merom New Instructions; 旧称Tejas New Instructions) という名称があった。登場当初はSSE4と呼ばれると一般的には思われていた。 45nm世代のCore 2のPenrynで搭載。47個の命令が追加になる。 Nehalemマイクロアーキテクチャの第1世代Intel Core iで初めて実装された。7個の命令を追加。SSE 4.2の追加命令は以下の通り。 String & Text New Instructions (STTNI) PCMPESTRI PCMPESTRM PCMPISTRI PCMPISTRM PCMPGTQ Application Targeted Accelerators (ATA) CRC-32 POPCNT - ビットが立っている数を数える AMD Phenomで搭載。 キャッシュ関連や挿入、展開の4命令が追加。インテルのSSE4とは名前は似ているが互換性は無い。 MMX/SSE後継のSIMD拡張命令セットで、呼称がIntel Advanced Vector Extensionsとなった。Sandy Bridgeマイクロアーキテクチャ（2011年 -）で初めて搭載された。浮動小数点演算の演算幅がSSEの2倍の256ビットとなり、1命令で8つの単精度浮動小数点演算もしくは4つの倍精度浮動小数点演算を実行することができる。また、命令デコード性能向上のため、新しい命令フォーマット（VEXエンコーディング）が採用されている。3 or 4オペランドの非破壊型命令もサポートするため、レジスタ退避・復元処理の記述を省くことができる。この非破壊型の命令フォーマットに関しては従来の128ビット幅のSSE命令にも使うことができるため、AVXに対応したプロセッサでは新規に導入された256ビット命令を使わなくてもSIMD演算の性能が向上する可能性がある。 SSEが導入された際には専用の128ビットレジスタが新設されたが、AVXの256ビットレジスタは下位の128ビットを既存のSSEレジスタと共有している。そのためSSE命令とAVX命令の間でのデータ交換は容易である。ただし、256ビットのAVX命令と既存のSSE命令を混在させると、SSE命令を実行する際にAVXレジスタの上位128ビットを退避するというペナルティが発生するため、パフォーマンスが落ちる。これを避けるためには、256ビット命令の実行後にVZEROUPPER/VZEROALL命令を実行して明示的にAVXレジスタの上位128ビットをクリアするか、SSE命令をVEXエンコーディングを使ったものに置き換える必要がある。VEXエンコーディングの128ビット命令はAVXレジスタの上位128ビットを保持せずにゼロクリアするという挙動になっており、AVXレジスタの部分的な書き換えが発生しないためである。 Sandy Bridgeでは当初のSSEの実装のように既存の128ビットの演算器を使って2サイクルで実行するようなことはせず、素直に乗算器や加算器などの演算器が256ビット幅に拡張されている。これによって、実質的なピーク浮動小数点演算性能がNehalem世代の2倍となっている。 AMDはBulldozer世代向けに当初予定していたSSE5拡張命令をキャンセルし、AMD FXではAVXがサポートされることになった。ただし、256ビット命令に関しては128ビット幅の演算器を2つ使って実行しており、スループットは従来のSSE命令と変わらない。 AVX2はAVXの後続となる256ビットレジスタ対象の拡張命令セットである。 256ビットレジスタ上の整数ベクトルに対する算術 (add, sub, mul, madd, abs, sad, sign)、比較（eq, gt）、統計 (ave, min, max)、論理 (and, or, xor, andnot) 、シフト (sll, sra, srl, alignr)、変換 (convert)、要素操作/swizzle (permute, shuffle, broadcast, insert, blend, unpack, pack, extract) をサポートする。また整数ベクトルの入出力 (stream load, masked load/store)、マスク生成 (movemask) も追加されている。シフト命令は要素ごとに独立したシフト量を設定できる。 浮動小数点ベクトルにも影響する命令としてはgather命令（非連続なデータを並べ替えながらロード）が導入されている。 インテルはHaswellマイクロアーキテクチャから搭載している。AMDはExcavatorアーキテクチャからAVX2を実装している。ただし、SIMD演算ユニット自体はZen+まで128bit幅に留まっていたため、AVX2命令を多用する処理はあまり高速化されていなかった。Zen2世代からは256bit幅になり処理速度が改善されている。 実装としてIntel CPUではベクトルレジスタとベクトル用実行ユニットを用いて計算される。例としてint8積和演算（VNNI等価）では"Vec Mul"および"Vec ALU"実行ユニットが典型的に利用される（下表）。 Intel AVX2 Vector Neural Network Instructions (AVX2 VNNI) は整数積和演算の効率化を目的とした拡張命令セットである。AVX-512のサブセットとして導入されたAVX512 VNNIをAVX2 (整数ベクトルレジスタ) へバックポートしている。[int8 | int16]・[非飽和 | 飽和] の組み合わせに対応した4種の整数積和演算（vpdp[bu|ws]sd[|s]）からなり、組み込み関数/intrinsicsとしては[XMM (_mm_) | YMM (_mm256_) ] およびAVX512 VNNIとの区別（_avx）をさらに組み合わせた計16個が定義されている。 Intel CPUではAlder Lakeから対応している。int8の場合FMAと同じ256bitレジスタを用いて4倍の要素を積和できるため、命令スループットが同等ならFMA比4倍の演算スループットを得られる。 ZMMレジスタを512ビット長とし、レジスタ数も16から32に増やした。 2012年、第1世代Xeon Phiに初めて搭載。 2015年、Xeonプロセッサ（Skylakeマイクロアーキテクチャ）から一部の命令を搭載した。 2018年、AVX512 VNNI(AVX-512 Vector Neural Network Instructions)が機能拡張としてIntel, IEEE Hot Chips 30 Symposium (HCS) 2018で発表した。 2019年、Intelの10nm世代CPUで（Sunny Coveコア）、AVX-512 を標準搭載とした。 2020年、Cooper Lakeマイクロアーキテクチャにて、bfloat16（AVX512_BF16）に対応した。 2022年、AMDは「Zen 4」コアでのAVX-512対応を表明した。 発表されている命令群には、扱うデータや処理の差によって、AVX512F, AVX512CD, AVX512DQ, AVX512PF, AVX512ER, AVX512VL, AVX512BW, AVX512IFMA, AVX512VBMI, AVX512VBMI2, AVX512VAES, AVX512BITALG, AVX5124FMAPS, AVX512VPCLMULQDQ, AVX512GFNI, AVX512_VNNI, AVX5124VNNIW, AVX512VPOPCNTDQ, AVX512_BF16といった分類がされる命令群があり、どれをどこまで実装しているかは、製品によって異なる。一部は命令の仕様だけ公開されていてまだ製品に実装されていないものもある。このように実装レベルが異なるものが複数存在していることもあり、AVX-512に対応しているといっても、何をどこまで実装されているのか確認が必要な状況になっている。 Alder Lakeでは2種類のコアを搭載している。PコアのみAVX-512命令セットが実行可能となっており、Gracemontアーキテクチャに基づくEコアでは非対応である。一部のマザーボードではBIOSバージョンとリビジョンの組み合わせにより、Eコアを無効化することでAVX-512を有効化できる。Intelは最新リビジョンのAlder LakeではAVX-512命令のサポートをシリコンレベルで打ち切っている。 AVX-512 Vector Neural Network instructions (AVX-512 VNNI) は畳み込みニューラルネットワークの整数演算（int8, int16）の効率を目的としたAVX-512のサブセットである。AVXでは高効率のINT8積和演算として VPMADDUBSW/VPMADDWD/VPADDD の3連続命令が利用されている（AVX2なら4要素積和演算を8レーン同時に実行可能）。VNNIはこれを VPDPBUSD 命令のみでおこなうものである。 インテルが2020年にAVX-512 VNNIの拡張として発表した（2次元）行列を計算するために設計された拡張命令。今までのは（1次元）ベクトル計算だった。2023年1月10日発売のSapphire Rapidsマイクロアーキテクチャから搭載されている。基礎となるAMX-TILEの命令群と、8bit整数の行列を扱うAMX-INT8の命令群と、bfloat16の行列を扱うAMX-BF16の命令群から構成されている。Sapphire RapidsマイクロアーキテクチャではTMUL（Tile Matrix Multiply、タイル行列積）が実装されている。 タイル行列積の1コアあたりの命令数/サイクル Intel AMX-INT8: 2048 (=16 * 64 * 2) Intel AMX-BF16: 1024 (=16 * 32 * 2) AVX-512はINT8で256op/cycleだったため、8倍高速化した。 未だ開発が継続されている命令群であり、さらなる拡張が予定されている。 x86プロセッサにおいて融合積和演算を実現するための拡張命令がFMAである。2007年にAMDがSSE5命令の一部として、2008年にインテルがAVX命令のサブセットとして採用を発表したが、両者の仕様は異なるものであった。その後、インテルは2009年初頭にFMA命令の仕様を変更し、4オペランド (FMA4) をやめ3オペランド形式 (FMA3) とした。2009年5月にはAMDがSSE5命令の採用を取りやめ、AVXのサポートを表明したため、仕様の統一が図られたかと思われたが、FMA命令に関してはインテルが仕様を変更する前の4オペランド版FMAを採用したため、FMA4とFMA3という二系統のFMA命令が混在していた。その後、AMDがZenマイクロアーキテクチャでFMA4の削除およびサポートの打ち切りを表明したことで、FMA命令についても仕様の統一が図られた。 FMA命令では±(A×B)±Cの形で表現される単精度/倍精度の浮動小数点演算を1命令で実行できる。乗算結果の符号を反転するか、乗算後に加算を行うか減算を行うかによって以下の4つのバリエーションがある。 MADD A×B＋C MSUB A×B－C NMADD －(A×B)＋C NMSUB －(A×B)－C いずれの命令も単精度/倍精度、スカラ/ベクタを問わず全てのタイプの演算に適用可能である。他にもベクタ専用のMADDSUB命令が存在し、1,3,5...番目の要素にMADDを、0,2,4...番目の要素にMSUBを行うという命令になっている。 FMA命令に対応した演算器においては、上記の浮動小数点演算を1クロックサイクルのスループットで実行可能で、加算のみ、乗算のみを実行できる演算器と比較すると理論FLOPSを倍にすることができる。また、乗算の結果に対しては丸めを行わず、加算を行った後に一度だけ丸めを行うため、乗算と加算を独立して実行するのと比較して丸め誤差を小さくできるという利点もある。実装としてはAMDではBulldozerマイクロアーキテクチャでサポートされたのが最初で、モジュールあたり2つの128ビットFMA演算器を搭載している。インテルはHaswellマイクロアーキテクチャで初めてサポートしており、コアあたり2つの256ビットFMA演算器を搭載している。 インテルが2008年に発表した時点でのFMA命令セット。完全な4オペランドを実現しており、3つのソースオペランドとディスティネーションオペランドを独立に指定できる。その後インテルは仕様を変更したために採用を取りやめたが、AMDはBulldozerマイクロアーキテクチャにおいてこの命令セットをサポートし続けていた。その後AMDが発表したZenマイクロアーキテクチャで削除されることとなった。 インテルが2009年に仕様を変更し、現在使われているFMA命令セット（FMA instruction set）。4オペランド方式をやめ、3つのソースオペランドのうち任意の1つを破壊することにより3オペランドでFMAを実現している。インテルはHaswellマイクロアーキテクチャ以降で、AMDはBulldozerマイクロアーキテクチャのPiledriverコア以降でサポートしている。なお、AMDが当初SSE5において採用したFMA命令も同じ3オペランド方式であった。 ベーシックなmm256_fmadd_ps命令の場合、Intel CPUで1サイクルあたり16個の単精度FMA演算を実行する (256 [bit/inst.] ÷ 32 [bit/fp32FMA] ÷ 0.5 [CPI=cycle/inst.])。例えば3GHzで動作するプロセッサであれば1コア当たり 48 GMAC/s (=96 GFLOPS) のピーク性能を可能にする（参考: FLOPS#代表的なハードウェアの浮動小数点数演算能力）。 FMA4と比べるとレジスタの退避を行う必要がある場合に不利であるが、命令長を1バイト短くすることができるため、デコーダの実装や命令キャッシュのフットプリントでは有利である。インテルのIvy Bridgeマイクロアーキテクチャ以降やAMDのBulldozerマイクロアーキテクチャでは、レジスタ・リネーミングによってレジスタ間のmov命令をゼロレイテンシで実行できるため、これと組み合わせればレジスタ退避のペナルティは軽減できる。 インテルのマイクロプロセッサにおいてはAVX2命令と同時に採用されたため、AVX2命令の一部であると誤解されることがある。しかし、両者のCPUIDフラグは独立に設けられており、必ずしも両者が同時にサポートされているとは限らない（例えば、FMA3をサポートするAMDのPiledriverコアではAVX2命令はサポートしていない）。 1999年 2月: インテルがSSE搭載のPentium IIIプロセッサを発表。 2000年 3月: インテルがSSE搭載のCeleronプロセッサを発表。 2000年 11月: インテルがSSE2搭載のPentium 4プロセッサを発表。 2002年 5月: インテルがSSE2搭載のCeleronプロセッサを発表。 2003年 3月: インテルがSSE2搭載のPentium Mプロセッサを発表。 2004年 1月: インテルがSSE2搭載のCeleron Mプロセッサを発表。 2004年 2月: インテルがSSE3搭載のPentium 4プロセッサを発表。 2004年 6月: インテルがSSE3搭載のCeleron Dプロセッサを発表。 2006年 1月: インテルがSSE3搭載のIntel Coreプロセッサを発表。 2006年 6月: インテルがSSSE3搭載のXeon 5100プロセッサを発表。 2006年 7月: インテルがSSSE3搭載のIntel Core 2プロセッサを発表。 2007年 8月: AMDがSSE5を発表。 2007年 11月: インテルがSSE4.1搭載のIntel Core 2プロセッサを発表。 2007年 11月: AMDがSSE4a搭載のPhenomを発表。 2008年 11月: インテルがSSE4.2搭載の第一世代Intel Core i7プロセッサを発表。 2011年 1月: インテルがAVX搭載の第二世代Intel Core i7プロセッサを発表。 2011年 10月: AMDがFMA搭載のAMD FXプロセッサを発表。 2013年 6月: インテルがAVX2搭載の第四世代Intel Core i7プロセッサを発表。 2016年 6月: インテルがAVX-512搭載のIntel Xeon Phiコプロセッサを発表。