MMX, SSE, AVX, FMA命令とは何かを明らかにしたい会

# 本稿について
- Intel系CPUの命令セットMMX, SSE, AVX, FMAが何か分からない(よく忘れる)...ので明らかにすることを目的とした記事です.
- かなり浅くまとめます. 間違ってたらご指摘ください. 実装は次回に回します.
- (2022.06 更新) 頂いたコメントを元に修正いたしました!

# tl;dr:
- MMXは整数演算, SSEは~~浮動小数点演算~~[^1]のSIMD処理を実現して高速化する命令.
- AVXがMMX/SSEの後継機, レジスタ長が倍になったりして性能が格段に向上.
- FMXはAVX2から搭載された積和演算のための命令.計算精度や演算性能が向上.
[^1]: SSE は整数演算と浮動小数点演算の両方に対応している, とのことです.

# そもそも命令セットアーキテクチャ(Instruction Set Architecture)とは?
- ハードウェアに指示を伝える命令のセット
- 算術等の命令の他に, レジスタの数・種類や割り込み・例外処理の方式, メモリ領域の確保方法なども含む. 実際に命令を与える時にはアセンブリ言語で記述.
- 代表的な命令セット: それぞれ32・64bitでレジスタとデータパスを実現
 * x86 : Intelが開発, IA-32とも呼ぶ.
 * IA-64 : IntelとHPが開発, 
 * AMD64 : AMD社が開発, x86命令を64bit対応させたもの.
 * ARM : ARM 社が開発, ARM系のCPU(組み込み系でよく採用されている)で使われている.
 * SPARC : [RISC型] サン・マイクロシステムズ社が開発, SPARC CPUで採用されている.
 * PowerPC : [RISC型]~~Appleが開発~~アップルコンピュータ、IBM、モトローラの提携によって開発. PowerPC CPUで採用されていた.
 * MIPS : [RISC型]MIPS Computer Systemsが開発. パタヘネにのってるやつ.
- 中でも今回はIntel系CPUの命令セットであるMMX, SSE, AVX, FMAについて簡単にまとめる。

# フリンの分類
- まとめる前に, フリンが定義した"計算機の分類"について触れる. 計算機でなくとも, イメージを共有するためにこれらの分類はよく使われる(と思います).
- SISD, SIMD, MISD, MIMDの4つが存在

## SISD (Single Instruction, Single Data stream)
- 単一命令で単一データを処理. 昔の逐次的な計算機.

## SIMD (Single Instruction, Multiple Data streams)
- 単一命令で複数データ(ストリーム)を処理. ベクトル計算機やGPUでの計算に加え, MMX, SSE, AVX, FMA命令らが属する.

## MISD (Multiple Instruction, Single Data stream)
- (異なるプロセッサらによる)複数命令で単一データを処理, 冗長性を確保したいシステムで使われる(らしい). 

## MIMD (Multiple Instruction, Multiple Data streams)
- 複数命令で, 異なる複数データを処理. CAD/CAMやシミュレーションに使われる.
- ~~MIMD型マシンは大きく共有メモリ型(UMA)と分散メモリ型(NUMA)に分類される~~[^2].
 - 参考 (UMA): http://www.atmarkit.co.jp/icd/root/12/16987612.html
 - 参考 (NUMA): http://www.atmarkit.co.jp/icd/root/77/44603477.html
- MIMDは, さらにSPMD(Single Program, Multiple Data streams)とMPMD(Multiple Program Multiple Data)に分類される.
[^2]: NUMA は共有メモリ型マルチプロセッサコンピュータに含まれるので、NUMA = 分散メモリという記述は誤りです。⇒https://ja.wikipedia.org/wiki/NUMA

# MMX
- 余っているレジスタを使って, データのSIMD処理を実現した命令拡張.
- ~~元々は, 当時持て余すことが多かった浮動小数点演算のレジスタを有効活用しようという動機~~.
- しかし浮動小数点演算処理を多様する処理(例. 3Dグラフィックス)は~~苦手~~できない[^3]. しかもユーザ側がMMX命令を明示的に使う必要がある.
- 整数演算処理は高速化が期待できる.
- ~~Pentium II~~ MMX Pentiumから搭載.
[^3]: http://kei-sakaki.jp/2013/08/17/misunderstood-mmx-technology/

# SSE
- x86アーキテクチャに8本の128bitレジスタ(通称: XMMレジスタ)を増やし, 浮動小数点演算のSIMD処理を実現.
- 歴史が長く, SSE, SSE2, SSE3, SSSE3, SSE4, SSE4.1, SSE4.2と改良され続けてきた:
- SSE
 - 命令数は70, Pentium IIIに実装された. 
- SSE2
 - 命令数は144, 64bit[^4]の倍精度浮動小数点演算のサポート, MMXを128bit幅に拡張する整数演算命令, キャッシュの制御などが改良された. 
- SSE3
 - 命令数は157, メモリアクセスや複素数計算の高速化, ~~仮想CPU~~ ハイパースレッディング対応 CPU 向けのスレッドの制御などが改良された.
- SSSE3
 - 命令数は189, 水平加算などが追加されて内積計算が高速化された.
- SSE4
 - SSE4.1とSSE4.2の二つある
 - SSE4.1
  * 命令数は236, 積和命令や丸め型命令等を追加して, ビデオエンコーディングといったメディア処理の能力を向上 (DivX 6.6.6では, SSE4を用いることで処理性能が60%向上).
 - SSE4.2
  * 命令数は243, テキスト処理の命令やCRC32演算命令などが追加. CRCの多項式自体はiSCSIなどの規格で使われており, 他にもRFCで規定されるような各種プロトコルのCRCを計算するために用いられる.
  
[^4]: SSE のレジスタ本数が 16 本に増えた.

>iSCSI : TCP/IPを使ってSCSIプロトコルを使うようにする規格
  http://www.wdic.org/w/WDIC/iSCSI
    SCSI : 周辺機器とコンピュータのハードウェア間でデータをやりとりするインタフェースのこと.  https://ja.wikipedia.org/wiki/Small_Computer_System_Interface
  

# Intel AVX (Intel Advanced Vector Extensions)
- MMX/SSEの後継で, 第2世代のCoreプロセッサ'Sandy Bridge'から搭載.
- 従来の命令セットと互換性をもたせたまま, 新しい命令フォーマットを導入.
- AVX, AVX2, AVX512が存在:
- AVX
 - 浮動小数点数演算の演算幅がSSEの倍(128bit*2 = 256bit)となるYMMレジスタが搭載.
 - レジスタ長が倍になったので, 単一命令で扱えるデータ数が倍増. つまり単一命令で, 単精度なら256bit/32 = 8つ, 倍精度なら256bit/64 = 4つを同時に演算可能.
 - 2オペランド命令だけでなく, 3, 4オペランド命令が追加された.
 
>MOV a,b から ADD a,b,c や MAC a,b,c,d (積和演算)など

- AVX2
 - 第4世代'Haswell'から搭載.
 - 浮動小数点のFMA(Fused Multiply Add)命令に対応 (次の節を参照).
 - 256bit長の整数演算のSIMD処理に対応.

- AVX-512
 - 通称AVX3.
 - YMMレジスタの倍, つまり512bit長に拡張されたZMMレジスタを用いた命令セットが追加.
 - レジスタ数も16から32に倍増.
 
# FMA
- 文字通り積和演算で使われる命令, これを命令セットレベルでサポートしているのが強い. FMA4形式とFMA3形式があるが今主流なのはFMA3. (違いはオペランド数)
- Intel AVX2命令セットから搭載されている.
- 今回はCPUだけ取り上げたが, DSPやGPUでもFMA命令がサポートされている.
- 乗算で丸めを行わないため, 計算精度が高い(誤差が低い).
- さらに1つの命令で2つの演算(乗算と足し算)ができるため, 演算のピーク性能が2倍となる.


# その他参考にした文献など
- http://journal.jp.fujitsu.com/2016/08/23/01/
- http://www.nminoru.jp/~nminoru/programming/arch/arch_features.html
- (図: https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AA%E3%83%B3%E3%81%AE%E5%88%86%E9%A1%9E#%E5%9B%B3%E8%A7%A3)
- https://en.wikipedia.org/wiki/MMX_(instruction_set)
- https://ja.wikipedia.org/wiki/Streaming_SIMD_Extensions
- https://en.wikipedia.org/wiki/FMA_instruction_set
- http://daily.belltail.jp/?p=1520
- http://math-koshimizu.hatenablog.jp/entry/2017/08/06/151212 

演算性能について:
https://qiita.com/bokotomo/items/a77e61c71ee92004679e