通用型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时钟周期进行估计.

 

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页