パタヘネ3.6~3章末です。並列処理のための命令に関する話です。
3.6
グラフィックシステムではデータの精度はそこまで必要ない代わりにデータのベクトルに対する操作が多く、それらをまとめて実行できる命令の需要がある。そのため、128ビットの加算器の桁上げチェーンをいくつかのパーティションに区切り、それぞれに対して同じ操作を行うことでデータを並列処理する仕組みが考えられた。このように、幅の大きな語の部分部分で処理を並列で行う仕組みを部分語並列性という。また、より一般的なデータレベル並列性にも該当する。他の言い方としてはSIMDもある。例として、ARMのNEONマルチメディア拡張は部分語並列性を実装している。この命令群では256ビットのレジスタを、8バイトのレジスタ32個、もしくは16バイトのレジスタ16個が連なっているものとして扱うことができる。データ型としては、8,16,32,64ビット符号あり/なし整数、32ビット浮動小数点数が扱える。
3.7
x86におけるSIMD命令はMMX、SSE、SSE2、EM64T、AVXなどと名前を変えて来た。AVXでは単一の操作で32ビット浮動小数点演算を8つ、64ビット浮動小数点演算を4つ実行できる。AVX以前のSSE,SSE2の操作は256ビットのYMMレジスタの下128ビットでおこなう。AVXの操作を行うためには、SSE2の命令の頭にvを付加した命令を使用する。例えば、addpd %xmm0, %xmm4はvaddpd %ymm0, %ymm4となる。なお、pdはpacked double precision floating point numberの頭文字。
3.8
Cイントリンシックを使用すればAVX命令を使用したコードがコンパイラによって生成される。x86intrin.hをインクルードし、__mm512d型変数や__mm512で始まる関数を呼び出すとAVX512命令が使用される。
3.9
左シフト命令は整数を2のべき乗倍するので、右シフトも2のべき乗で除算する効果があると考えるかもしれないが、符号ありの場合、符号ビットが変化するので除算にならない。では符号拡張すると除算になるかというと、ビット数の限界から最下位ビットが落ちるので厳密な除算とはならない。
浮動小数点数同士の加算では、精度の限界から結合則が成り立たない。例えばa=-1.5×10^38とb=1.5×10^38とc=1の足し算では、a+bを先に行ってcを足すと1、c+aを先に行ってbを足すと0となる。このことから、演算の順序が保証されない並列処理を行うと、計算結果が毎回異なったりする。整数の場合は大きな数値と小さな数値を足してもオーバーフローしなければ結合則が成り立つので、この現象は起こらない。
MIPSの符号なし即値加算命令addiuは16ビットの即値フィールドを符号拡張する。符号なしと言っているのに、符号拡張されるため間違いやすいが、こうなっている理由は、負の数を加算できるようにするため。即値減算命令が無いのでこうせざるを得ない。
浮動小数点数の演算精度は理論数学者だけの問題ではなく、一般のユーザーにも関係がある。Pentiumの浮動小数点除算アルゴリズムでは、商の予測を使用していたが、参照表の内容を誤った理解のため一部0としていた。その結果除算結果の12~52ビット目が誤差を持つようになった。一般のスプレッドシートユーザーはこの問題の影響を27000年に1回しか受けないとIntelは発表したが、IBMの研究所は24日に1回と主張した。結果、Intelは520億円の費用を投じてプロセッサ回収・交換に追い込まれた。
コメント