実際に VGATHER 系命令とVGATHERと等価なことを要素ごとにバラして行うコードのベンチマークを取ってみました。

プログラムはこちら

計測条件は、データは全て1次キャッシュに乗っており、全ての要素をアクセスする(マスクレジスタは実質使われない)、です。なお、マスクによる性能の変化を見るために、1つだけマスクを使ったケースも計測します。

VGATHER 系命令はマスクレジスタがクリアされるとかデスティネーションレジスタとベクタインデックスレジスタに同じものを指定できないとかのベンチマークを取るには問題となる仕様があり、その仕様を回避するために余計な命令が挟まっているせいで計測に結構な(1クロックぐらい?)誤差があるものと思われます(特にレイテンシ)。

では結果。いつも通り前がレイテンシで後ろがスループットの逆数です。要素ごとにバラした奴は数十命令から構成されていて、ちゃんとスループットを測るのが大変(or面倒)なので、レイテンシだけです。

VPGATHERDD (xmm) 14-9
VPGATHERDD (ymm) 19-12
VPGATHERDD (ymm) 半分 19-12
VPGATHERQQ (xmm) 12-7
VPGATHERQQ (ymm) 17-9
要素ごとにバラしてDWORDロード (xmm) 15
要素ごとにバラしてDWORDロード (ymm) 33

※ 半分 というのは、マスクレジスタを使って8要素のうち4要素だけメモリアクセスするようにしたもの。

別に VGATHER 遅くないじゃん。少なくとも、4要素の時点で要素ごとにバラすより VGATHER した方が速い。あと、ここで注目すべきは、マスクレジスタによってアクセスする要素を減らしている場合でもレイテンシもスループットも変わっていないという点で、ソースレジスタの内容による最適化は一切されていないということがうかがえます。さすがにこれは次で改善されるでしょう。せめてマスクによる最適化ぐらいは実装してほしいものです。

ちなみに、Haswell では1次キャッシュのロードレイテンシは4クロックでロードは同時に2つ発行できる(スループットの逆数が0.5になる)ため、8要素ロードしようとするとレイテンシの下限が7でスループットの逆数の下限は4となります。IDF の発表では「Relatively high latency and low throughput on Haswell」だったのですが、手で書くよりは速いけどあまり期待しすぎないでね、というニュアンスなのかもしれません。

しかし、w_oさんの結果と全然違うんですがこれは一体…

Trackback

no comment untill now

Add your comment now