簡単なベクトル命令のベンチマークを作って、動かしてみようと思う。
作ったのはAXPYで、単純に2つのベクトル要素をロードして足し算して、ベクトルストアするだけだ。
一応ベンチマーク自体は正しく動くようになったのだが、思ったほど性能が出ていないので解析している (32ビットint型を300個処理するのに758サイクル)。 DLEN=128にしているので1サイクルあたり4要素処理できるとして、2種類のベクトル要素のロードに(300/4)*2 = 150, さらにベクトルストアの75サイクルを積み上げて、ベクトル加算はこれらのメモリアクセスとオーバラップしているものとする。 そうすると225サイクルで済むはずなのに、その3倍近くかかっている。
問題なのは、常にL2にヒットするようにしている(つまりL1DキャッシュをWarmupしていない)ので、LSUの中でリプレイが発生してバンド幅を1/2にしている。 これに対してはMSHR内にReplay Queueを保持するなど何らかの方法はありそうな気がしている。
これを確認するためには、一度すべてL1Dキャッシュを埋めてしまう(L1D Warmup)。 そして実際のベンチマークを走らせてみよう。
preload (DATA_SIZE, input1_data); preload (DATA_SIZE, input2_data); preload (DATA_SIZE, results_data); // Do the vvadd setStats(1); vvaddint32( DATA_SIZE, input1_data, input2_data, results_data ); setStats(0); // Check the results // return verify( DATA_SIZE, results_data, verify_data ); }
これでも378サイクルだ。まだ遅いなあ。