汎用型C/C++プログラム性能テストBenchmarkの簡単な実現


アルゴリズムの改良が完了した後、人工的に時間の複雑さを推定するほか、既存の性能分析ツール、例えばIntelなどの改善効果を直感的に検出することを望んでいるかもしれません.® VTune™ Amplifierは自然にニーズを満たしていますが、サードパーティ製のツールを使用するコストが私たちのニーズを超えている場合があります(おそらく、大まかな比較だけで結果が得られるかもしれません)、コードの中でテストプロセスを制御することを望んでいる場合があります.この場合、Benchmarkを書くのが第一選択です.
本論文は簡単な汎用型Benchmarkフレームワークを実現した.簡単なため、得られる情報も限られているが、これは十分である.(より強力なframeworkが必要な場合は、Celero,C++Benchmark Authoring Library/frameworkを推奨します)
 
//compiled with /UNICODE
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <RLib_Import.h>

#if _DEBUG
#pragma comment(lib, "RLib_d.lib")
#else
#pragma comment(lib, "RLib.lib")
#endif // _DEBUG

using namespace System;

//-------------------------------------------------------------------------

static Timer timer; //Timer       API QueryPerformanceCounter      

//-------------------------------------------------------------------------

static void show_benchmark_result(double interval, const String &prefix = Nothing)
{
	GlobalizeString u_prefix(prefix + _T("    :") + String().Format(_T("%f"),
		 interval * 1000) + _T("ms") RLIB_NEWLINE);
	printf(u_prefix.toGBK());
}

//-------------------------------------------------------------------------

#define SAMPLE_COUNT 1024 //    
void test1()
{
}

//-------------------------------------------------------------------------

void test_wrapper(RLIB_TYPE(test1) *test_t, const String &test_name)
{
	printf(RLIB_NEWLINEA);

	double intervals[SAMPLE_COUNT];
	for (int i = 0; i < RLIB_COUNTOF(intervals); ++i) {
		timer.BeginTimer();
		test_t();
		timer.EndTimer(); 
		intervals[i] = timer.GetDoubleTimeSpan();

		//show_benchmark_result(intervals[i]);
	} //for

	double imin = intervals[0], imax = intervals[0];
	for (int i = 1; i < RLIB_COUNTOF(intervals); ++i) {
		intervals[0] += intervals[i];
		imax = max(imax, intervals[i]);
		imin = min(imin, intervals[i]);
	}
	show_benchmark_result(imin, _T("  "));
	show_benchmark_result(imax, _T("  "));
	show_benchmark_result((intervals[0] - imax - imin) / (RLIB_COUNTOF(intervals) - 2),
						  test_name + _T("   "));
}

//-------------------------------------------------------------------------

int _tmain(int argc, _TCHAR* argv[])
{
	test_wrapper(test1, _T("    "));
	printf(RLIB_NEWLINEA);
	system("pause");
	return argc;
}

また、APIを呼び出すことが容易でない場合には、rdtsc命令により、おおよそのCPUクロック周期を推定することも可能である.