IDF 2012で、2013年に登場と見られるIntelの次世代プロセサ「Haswell」のアーキテクチャが発表された。Haswellのアーキテクチャ全般については大原雄介氏の記事を参照戴くのが分かり易いと思うが、それを補足する意味で、HPC(High Performance Computing)向けの強化ポイントについて詳細に見て行きたい。

Haswellで一番目に付くのは、各コアに256bit長(64bit×4)のFMA演算器を2個装備し、1サイクルに倍精度の浮動小数点演算を16回実行できるようにした点である。また、32bitの単精度浮動小数点なら32回の演算を実行できる。

「京」スパコンに使われている「SPARC64 VIIIfx」とその後継の「SPARC64 IXfx」のコアは8演算、2012年6月にTop500 1位となった「Sequoia」に使われている「BlueGene/Q(BG/Q)」も8演算であるので、これらのスパコン向けのコアの2倍の倍精度浮動小数点演算能力を備えている。

IntelのXeonプロセサは、スパコンランキングTop500の500システム中の372システムで使われている一番メジャーなプロセサであるが、今回のHaswellでは、その地位をさら強化しようとしているように見える。Intelは認めないであろうが、筆者には、汎用プロセサのXeonチームからみればメニーコアのXeon Phiは最大の競争相手で、 HPC市場を奪われまいと対抗意識を燃やしているという感じがする。

実行パイプラインの強化

Ivy BridgeからHaswellへの大きな機能強化は、命令を発行するポートが2ポート追加された点と、ポート0と1にFMA(Fused Multiply Add)演算器が追加された点である。命令のデコードは単純命令が3命令と複雑な命令が1命令という点は変わっていないのであるが、2つのFMA演算、2つのロード命令と1つのストア命令が並列に発行できるようになり、科学技術計算で命令の発行がボトルネックになるケースが減り、性能が上がる。

Haswellでは命令を発行するポート6、7が追加され、ポート0、1にFMA演算器が装備された(このスライドを含み、以下のスライドは、IDF 2012 Fallにおける発表スライドの抜粋)

FMA演算は積和演算と何が違う?

浮動小数点数は、1.xxxxx ×(2のyy乗)と言う正規化された形で表され、xxxxxは倍精度浮動小数点数の場合は52bitの2進数である。このような数同士を掛けると、小数点以下のビット数は2倍になるが、これでは64bit長の倍精度浮動小数点数に収まらなくなってしまう。そのため、小数点以下のビット数を52bitとするように丸めを行う。

(A×B)+Cという演算では乗算と加算が行われるが、通常の浮動小数点演算でこれを行うと、A×Bを計算して丸めを行い、その結果とCを加算することになる。FMAのFはFusedの意味で、FMA演算のA×Bと+Cは融合(fuse)しておりA×Bの結果に対して丸めを行わず、無限精度の乗算結果にCを加算する。そして、この加算の結果に丸めなどを行い、(A×B)+Cの答えを出す。

FMA演算が通常の積と和の演算に比べて優れているのは、A×Bに対して丸めを行わず、無限精度で計算するので、計算誤差が小さくなる点と、A×B、丸め、+C、丸めと計算する場合と比べて演算に必要なサイクル数が少ない点である。また、(A×B)+Cという形式の計算でないとダメであるが、この形に嵌れば、1つの命令で2つの演算ができ、ピーク演算性能が2倍になる。

このため、SPARC64 VIIIfx/IXfx、POWER7、BG/Qなどのスパコン向けプロセサはFMA演算をサポートしており、IntelのHaswellもAVX2命令セットのサポートによって、これらと並ぶことになる。

FMA演算はどう使うのか

FMA演算は(A×B)+Cを計算する。SPARC64などでは結果を格納する第4のレジスタDが指定できるので問題ないのであるが、 Haswellの場合は、3つしかオペランドを指定できない命令形式であるので、計算結果をどこに入れるかという問題がある。Haswellでは、この問題を次のように解決している。

HaswellのFMAはオペランドの指定の違いで、同じ演算の命令が3種類ある

HaswellのAVX命令セットでは、同じFMA演算に対して3つの異なる命令を用意している。上の例はVFMADDというベクトルのFused Multiply ADD命令であるが、VFMADD132とVFMADD213、VFMADD231と3種の命令がある。この命令に続いて、上の図の例では、ymm8、ymm9、mem256と3つのオペランドが指定されている。この3つのオペランドは順に、src1、src2、src3と呼ばれる。そして、命令の最後の231はA、B、Cがどのオペランドであるかを示しており、Aは2番目のオペランドのsrc2、Bは3番目のオペランドのsrc3、Cは1番目のオペランドのsrc1となることを指定している。オペランド指定の全ての順列組み合わせは6通りあるが、AとBは入れ替わっても結果は同じであるので、上記の3通りの順番が指定できれば十分である。そして、FMA演算の結果は、常にsrc1に格納される。

科学技術計算で良く出てくる演算は、ベクトルの内積で

という計算である。これはSum=Xi×Yi+Sumをi=0から順に計算していけば良い。そして、この場合は(A×B)+CのCに結果を格納する必要があり、VFMADD231命令が使われることになる。もう1つ、良く使われるケースは、

An×Xn+An-1×Xn-1…A1×X+A0

のような高次の多項式の計算で、これを(((An×X)+An-1)×X+An-2)×X+An-3…とように順に計算する場合である。このケースは演算結果の(An×X)+An-1をAオペランドに格納する必要があり、VFMADD132命令を使い、Anをsrc1、Xをsrc3、An-1をsrc2に入れてやれば良い。そうすれば次の回は、src1にはAn×X+An-1の結果が入っているので、src2にAn-2を入れて演算すれば((An×X)+An-1)×X+An-2がsrc1に得られる。

YMMレジスタは16本あるので、結果を格納するレジスタを任意に指定しようと思うと命令に4bitのレジスタ指定フィールドが必要となるが、3種のオペランド順の指定なら2bit弱で済むので、このような指定法が用いられていると思われる。

そして、演算には次の20種のバリエーションがある。ただし、ps、pd、ss、sdは256bitのレジスタに複数のデータを詰め込むpacked形式か、1つだけのsingle形式かと、各データが単精度(s)か倍精度(d)かの指定であり、演算の種別と言う点では6種である。

6種の演算とデータの形式(ps、pd、ss、sd)で、全体では20種の命令がある

最初の4つのvFMAdd、vFMSub、vFNMAdd、vFNMSub命令はCとA×Bの符号が+か-かのバリエーションで、それぞれの計算で必要な符号の演算を選択すれば良い。

大原氏は、こんなに種類が必要かと書いておられるが、答えはYes and Noで、確かに符号を反転する命令を1つ加えれば、これらの4種のバリエーションは必要ない。しかし、このスライドの下に書いてあるように、この1つの符号反転命令を不要にしたいというのが、これらのバリエーションを作った理由である。また、コンパイラの開発者には、このように対称性のある命令が好まれる。さらに、整数命令の命令コードスペースはあまり空きが無いが、FMA命令を入れる浮動小数点命令の命令コードには空きが多いので、こられの命令を作るスペースがあるし、符号の反転に必要なハード的な負担も非常に少ない。ということで、SPARC64やPOWERアーキテクチャでも、これらの4種のバリエーションを持っており、Intelも同様の理由から採用したのであろう。

(中編に続く)

■Intel 次世代プロセッサ「Haswell」関連記事
【レポート】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日)