Core2は積と和ができると信じているが
for (i=0; i<N; i++) { asm volatile ("" "mulpd %0, %1\n\t" "addpd %2, %3\n\t" "mulpd %4, %5\n\t" "addpd %6, %7\n\t" "mulpd %0, %1\n\t" "addpd %2, %3\n\t" "mulpd %4, %5\n\t" "addpd %6, %7\n\t" "mulpd %0, %1\n\t" "addpd %2, %3\n\t" "mulpd %4, %5\n\t" "addpd %6, %7\n\t" "mulpd %0, %1\n\t" "addpd %2, %3\n\t" "mulpd %4, %5\n\t" "addpd %6, %7\n\t" "addpd %6, %7\n\t" "xorpd %1, %1\n\t" "xorpd %3, %3\n\t" "xorpd %5, %5\n\t" "xorpd %7, %7\n\t" :"+x"(a), "+x"(b), "+x"(c), "+x"(d), "+x"(e), "+x"(f), "+x"(g), "+x"(h) :"m"(cache[0])); }
ちゃんとできる。上のが9.0 〜 9.5cycleくらい(なんかループのアラインによって変わる)
最後のaddは入れたほうが速い。なぜか。
ただ、cycleあたり2つの出力だと、4cycleでレジスタを使いきってしまい、mulpdのレイテンシ5を隠蔽できない。
ピーク性能を出すには、CoreMAのパイプラインを完全に理解し、適切な位置でロードしたりストアしたりしてあげる気遣いが大切なのである。
(実際、Core2は1cycleにひとつだけロード付き命令が実行できる(検証してない)ので不可能ではないはず)
上のはxorして日和ってる。