首页
社区
课程
招聘
[原创]精密计时器的使用
发表于: 2013-6-29 20:49 5824

[原创]精密计时器的使用

2013-6-29 20:49
5824
最近想测试一下自己写的函数效率如何,所以就研究了一下计时器的实现方法,发现,要实现精密计时,主要有两种方法,一种是VC内嵌汇编,另一种是api,下面是我实现的代码,如果有需要的朋友可以直接copy.
但是在程序实际运行的时候两种计时方式得出的数据不一致,如果有哪位大虾看出哪里有bug,请狂喷
此程序运行结果为:汇编测得的两种方法时间相差无几,但奇怪的是使用数组方法居然比vector要慢,更奇怪的是使用api的方法得出的结果vector使用的时间竟然达到了数组的8倍之多
此前我还做过一个实验,单独使用汇编测定时间,vector所用的时间也会达到数组的几倍,而不是此程序里的结果
这些问题让我百思不得其解
                #define u32 unsigned _int32
                #define u64 unsigned _int64
void main()
{
	_wsetlocale(LC_ALL, L"chs");
	/*************************************************************************************************************************/
	//以下是汇编计时方法
	//vectgor计时第一次
	BIT64 m1,m2,m3,m4,m5,m6;
	_asm
	{
		RDTSC
		mov dword ptr[m1],EAX
		mov dword ptr[m1 + 4],EDX
	}
	/*************************************************************/
	//函数体
	std::vector<u32> v1(100000000);
	u32 i = 0;
	while(i < 100000000)
	{
		v1[i] = i;
		i++;
	}
	/*************************************************************/
	//vector第二次计时
	_asm
	{
		RDTSC
		mov dword ptr[m2],EAX
		mov dword ptr[m2 + 4],EDX
	}
	/*************************************************************/
	//array第一次计时
	_asm
	{
		RDTSC
		mov dword ptr[m3],EAX
		mov dword ptr[m3 + 4],EDX
	}
	/*************************************************************/
	u32* v2 = (u32*)malloc(400000000);
	u32 n = 0;
	while(n < 100000000)
	{
		v2[n] = n;
		n++;
	}
	/*************************************************************/
	//array第二次计时
	_asm
	{
		RDTSC
		mov dword ptr[m4],EAX
		mov dword ptr[m4 + 4],EDX
	}
	free(v2);
	/*************************************************************/
	//计算CPU频率
	_asm
	{
		RDTSC
		mov dword ptr[m5],EAX
		mov dword ptr[m5 + 4],EDX
	}
	Sleep(1000);
	_asm
	{
		RDTSC
		mov dword ptr[m6],EAX
		mov dword ptr[m6 + 4],EDX
	}
	u64 CPUFrequency = *((u64*)&m6) - *((u64*)&m5);
	/*************************************************************
	以下是api计时方法*/
	LARGE_INTEGER Frequency,FrequencyStart,FrequencyEnd,FrequencyStart1,FrequencyEnd1;//精确计数器频率
	QueryPerformanceFrequency(&Frequency);//获得计数器频率
	QueryPerformanceCounter(&FrequencyStart);
	/*************************************************************/
	//函数体
	std::vector<u32> v3(100000000);
	u32 j = 0;
	while(j < 100000000)
	{
		v3[j] = j;
		j++;
	}
	/*************************************************************/
	QueryPerformanceCounter(&FrequencyEnd);
	/*************************************************************/
	QueryPerformanceCounter(&FrequencyStart1);
	/*************************************************************/
	//函数体
	u32* v4 = (u32*)malloc(400000000);
	u32 k = 0;
	while(k < 100000000)
	{
		v4[k] = k;
		k++;
	}
	/*************************************************************/
	QueryPerformanceCounter(&FrequencyEnd1);
	free(v4);
	/*************************************************************/
	std::cout << "\n本次测试分别对vector和array进行100000000个数据填入,并且使用汇编和api两种方法进行比对,分别得出两者所用的时间,单位为秒:\n" 
			  << "汇编测得'Vector'所用时间为:\t" << (double)(*((u64*)&m2) - *((u64*)&m1) / CPUFrequency) << std::endl
		      << "汇编测得'Array'所用时间为:\t" << (double)(*((u64*)&m4) - *((u64*)&m3) / CPUFrequency) << std::endl
			  << "api测得'Vector'所用时间为:\t" << ((double)(FrequencyEnd.QuadPart - FrequencyStart.QuadPart) / (double)Frequency.QuadPart) << std::endl
			  << "api测得'array'所用时间为:\t" << ((double)(FrequencyEnd1.QuadPart - FrequencyStart1.QuadPart) / (double)Frequency.QuadPart) << std::endl;
	std::cout << "汇编测得CPU主频为:" << (double)CPUFrequency /1024 /1024 /1024 << "\tGHZ" << std::endl;
	/*************************************************************************************************************************/
	system("pause");
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 1042
活跃值: (470)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Make, 学习了 感谢楼主。
2013-6-29 20:58
0
雪    币: 758
活跃值: (42)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
漏了一个BIT64的定义,直接把这个写成double就可以了,大小是一样的
2013-6-29 21:03
0
雪    币: 154
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
timeBeginPeriod
timeGetTime
timeEndPeriod
2013-6-29 21:30
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
虽然暂时还用不到,但还是觉得很有帮助
2013-6-29 21:34
0
雪    币: 758
活跃值: (42)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
发现Bug的所在了,请用下面代码替换对应行
                          << "汇编测得'Vector'所用时间为:\t" << ((*((u64*)&m2) - *((u64*)&m1)) / (double)CPUFrequency) << std::endl
                      << "汇编测得'Array'所用时间为:\t" << ((*((u64*)&m4) - *((u64*)&m3)) / (double)CPUFrequency) << std::endl
2013-6-29 23:25
0
雪    币: 376
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
现在CPU都是自动调频的,QueryPerformanceFrequency这个是不准的
2013-6-30 08:35
0
雪    币: 758
活跃值: (42)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
楼上能细说一下是怎么回事么,大家一起交流学习一下

另外经过bug修正,此程序在我的2.6GHZ电脑上汇编和api方法得到的数据基本一致,汇编方法能比api精确一些
2013-6-30 12:35
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
http://delphi.cjcsoft.net/viewthread.php?tid=1570
Sleep(1000)唤醒后,不一定就过了1000ms,可能多,Windows不是一个实时系统
多核环境下RDTSC问题有点多
2013-6-30 21:51
0
游客
登录 | 注册 方可回帖
返回
//