一次元配列の総和を求めるプログラムを応用して、C++言語で記述したプログラムと、アセンブリ言語で記述した関数を利用したときの性能差を検証してみましょう。
arques.hatenablog.com
符号付64ビット整数型
性能評価プログラム
C++で記述した関数と、アセンブリ言語で記述した関数を複数回呼び出します。それぞれに要した時間をclock関数で計測し、性能を評価します。common.hやアセンブリ言語で記述した関数は「総和」で示したものと同じです。以降に、呼び出し側のソースリストを示します。
#include "..\common.h" // TEMPLATES #define T long long extern "C" T aaddq(const T*, const size_t); // main int main(void) { const size_t ArrLen = 32768; static_assert(ArrLen % 16 == 0, "number of elements must be an integral multiple of 16."); //T a[ArrLen]; try { T cr, ar; T* a = (T*)_mm_malloc(sizeof(T) * ArrLen, 64); clock_t start; init(a, ArrLen); #define LOOPS 10000 for (size_t j = 1; j < 10; j++) { start = clock(); for (int i = 0; i < LOOPS;i++) { a[0] = (T)0; cr = cadd(a, ArrLen); } print_elTime("cpp: ", start, clock()); start = clock(); for (int i = 0; i < LOOPS;i++) { a[0] = (T)0; ar = aaddq(a, ArrLen); } print_elTime("asm: ", start, clock()); if(cr != ar) printf("***** error\n"); cout << fixed << setprecision(2); cout << "cpp = " << (int)cr << endl; cout << "asm = " << (int)ar << endl; } _mm_free(a); } catch (char* str) { cerr << str << endl; } return 0; }
これまでと同様に、時間の計測を行います。上記プログラムへ /O2 オプションを指定してビルド&実行したときの性能を示します。
アセンブリ言語で開発した関は、C++言語で開発した関数より約4.1倍高速です。