中編はコチラ

不連続のメモリアドレスをアクセスするスキャッタ/ギャザー命令

A[i]+B[i]→C[i]のような連続アドレスのメモリをアクセスする場合は簡単であるが、行列積ではkを0からnまで順にC[i、j]+=A[i、k]×B[k、j]を計算するという処理になる。この時、A[i、k]がkの順にメモリ上に並んでいるとすると、B[k、j]はjの順にメモリ上に並んでおり、連続アドレスではなく一定の距離をもった飛び飛びのアドレスのアクセスになる。また、非ゼロの要素が大部分の粗行列では各行の非ゼロの要素の列番号がメモリ上に連続して書いてあるというようなデータ形式が用いられる。この場合は、不規則な距離をもつ飛び飛びのアドレスのアクセスになる。

このような飛び飛びのメモリアドレスのデータを読み出して、YMMレジスタに順に詰め込む処理をギャザー(Gather)、この逆にレジスタ上では並んでいるデータを飛び飛びのアドレスに格納する処理をスキャッタ(Scatter)という。スキャッタ/ギャザー機能は、多くの要素をまとめて扱うベクトルプロセサでは必須の機能であるが、1つひとつのデータを扱うスカラプロセサでは必要が無かった。しかし、AVXでYMMレジスタが256bitと、かなり要素数の多いデータを扱うようになったことからこの機能がサポートされるようになった。

ギャザー命令では、EAXレジスタで指定したベースアドレスから、Index(この例ではymm0)レジスタで指定したオフセットのアドレスのデータを取り出して結果レジスタに格納する

VGATHERDPS命令は、単精度のデータをギャザーする命令であるので、1つのYMMレジスタには8個の要素が入る。この例ではIndexレジスタであるymm0に、右から、0、17、2、…という値が入っている。最初のデータのIndexはゼロであるので、EAXで指されたベースアドレス+0から読まれる。その次は17であるが、これは4バイトの単精度データで17個分のオフセットという意味であるので、EAX+68バイトの位置の17.7というデータが読まれる。このように、EAXレジスタで配列の先頭アドレスを指し、Indexレジスタに要素番号を入れておけば、その要素番号のデータが結果レジスタに入る。

また、この図では説明されていないが、マスクレジスタ(この例ではymm2)を使うことができる。この例では32bitのマスク要素の値が非0の結果レジスタの要素だけにメモリからのデータを格納し、マスクの値が0の要素は元のデータを保持する。

そして説明は省略するが、これらのギャザーの逆にymmレジスタの各要素をEAXとIndexレジスタで指定されるアドレスのメモリに格納するスキャッタ命令が用意されている。

このようにスキャッタ/ギャザーは便利な機能であるが、ハードウェア的には1サイクルには1つのキャッシュラインのアクセスに限定されており、アクセスするアドレスがバラバラで複数のキャッシュラインにまたがる場合は、関係するキャッシュラインの数だけ、スキャッタ/ギャザー処理にかかるサイクル数が増えることになる。

YMMレジスタ内のデータの入れ替え命令も強化

HaswellのAVX2ではレジスタ内のデータの入れ替え命令が多く追加されているが、その中でも使いでがありそうで、強力なのがVPERM命令である。

Index(ymm2)で指定したソース(ymm3)レジスタの要素を結果(ymm1)レジスタに入れるVPERM命令

VPERM命令では、結果(この例ではymm1)レジスタの各要素は、対応するIndex(この例ではymm2)レジスタの要素が指定するソース(この例ではymm3)レジスタの要素を格納する。この図では、Indexの最初の要素は0であり、ymm3の第0要素の0.1fという値がymm1の第0要素に格納される。また、Indexの第1要素も0であり、ymm1の第1要素も0.1fとなる。その次のIndexの第2要素は3であり、ymm3の第3要素の0.4fがymm1の第3要素に格納される。

このように、VPERM命令は結果レジスタのそれぞれの要素に対してソースレジスタの任意の要素を入れることができ、非常にフレキシビリティの高い命令である。ただし、Haswellの実装ではymmの上半分の128bitと下半分の128bitの間には仕切りがあるようで、この仕切りを超えるデータ移動が無い場合は1サイクルで実行きるが、上半分の要素を下半分の要素に入れるというような仕切りを超えるデータ移動がある場合は3サイクルを必要とするようである。

ここでは説明を省略したが、これも新設されたVBLEND命令と、従来からあるVSHUF命令を組み合わせると、次の図のように4命令で、4行4列の行列の転置(行と、列の方向の入れ替え)を行うことができる。1要素ずつ処理すると少なくとも15命令を必要とし、これらのシャッフル命令を使うと、大幅に高速に行列の転置が可能となる。

VPERM命令とVBLEND、VSHUF命令を使って4行4列の行列を転置する例

HaswellのAVX2では、多くの整数命令もデータサイズが128bitから256bitに拡張され性能がアップしているが、ここでは、科学技術計算向けの機能強化を取り上げて説明を行った。

サーバ用のHaswellが何コアになり、クロック、消費電力がどの程度になるのかは現状では不明であるが、コアの設計としては、IBMのBG/Qや富士通のSPARC64 IXfxと十分対抗できるHPCシステム向けのプロセサとなっており、このHaswellのHPC性能を追求するという路線は、スパコン用のIBMのBlueGeneや富士通のSPARC64 IXfxだけでなく、GPUやXeon Phiに対する挑戦と言える。

■Intel 次世代プロセッサ「Haswell」関連記事
【レポート】HPC性能が大幅に強化されたHaswell(中編) (2012年10月4日)
【レポート】HPC性能が大幅に強化されたHaswell(前編) (2012年10月3日)
【レポート】IDF 2012 - 次期Intel Core「Haswell」の内部構造を探る - Uncore(GPU/Media Block)編 (2012年9月25日)
【レポート】IDF 2012 - 次期Intel Core「Haswell」の内部構造を探る - マイクロアーキテクチャ編 (2012年9月18日)
【レポート】IDF 2012 - 次期Intel Core「Haswell」の内部構造を探る - 拡張命令(AVX2/TSX)編 (2012年9月18日)
【レポート】トランザクションメモリのサポートが明らかとなったIntelのHaswell (2012年2月16日)