ベンチマーク
次の様なコードを書いてベンチマークを取りました。
#include <stdio.h> #include <stdlib.h> #include <xmmintrin.h> #include <windows.h> template<int N> int f2i(float f) { return (int)f; } template<> int f2i<1>(float f) { return _mm_cvttss_si32(_mm_load_ss(&f)); } template<> int f2i<2>(float f) { return _mm_cvttss_si32(_mm_set_ss(f)); } template<> int f2i<3>(float f) { _asm { movss xmm0, f cvttss2si eax, xmm0 } } template<> int f2i<4>(float f) { _asm { cvttss2si eax, f } } template<int N> void process(float f) { LARGE_INTEGER li; QueryPerformanceCounter(&li); int sum = 0; for(size_t i = 0; i < 1024 * 1024; i++) { f *= f; sum += f2i<N>(f); } LARGE_INTEGER liEnd; QueryPerformanceCounter(&liEnd); printf("sum=%d TIME=%u\n", sum, (int)(liEnd.QuadPart - li.QuadPart)); } int main(int argc, char* argv[]) { float f = atoi(argv[1]); process<0>(f); process<1>(f); process<2>(f); process<3>(f); process<4>(f); }
VC8 /OxなコードをCore Duo T2500上での結果は、だいたい理想的な結果の奴だと、
sum=234740 TIME=1470631 sum=234740 TIME=1418952 sum=234740 TIME=1409258 sum=234740 TIME=1421215 sum=234740 TIME=1404352
のような感じ。キャスト版が群を抜いて遅いが、それ以外は、誤差のようなものか。
おもしろいのは、VC7.1 (.NET 2003)での結果。
sum=-958466572 TIME=2900252 sum=234740 TIME=1338547 sum=234740 TIME=1347701 sum=234740 TIME=1904928 sum=234740 TIME=1857062
キャスト版の結果だけ違うし、速度も他と比べて2倍程度違う。ここまで遅いと他の処理方法を考えたくなるのは当たり前。そして、面白いことに、組み込み関数版が最も速いだけではなく、VC8のコードの速度を上回っている。それもぶっちぎりで。アセンブラ版は最適化の度合いが低いせいか、VC8のキャストよりも断然遅い結果に。