QueryPerformanceFrequency 结果不正确

时间:2023-01-20 16:04:10

while (getch(), 1)
{
LARGE_INTEGER x ;
BOOL b = QueryPerformanceFrequency(&x) ;
cout <<b <<endl ;                    // 这里是 1 没问题
cout <<x.QuadPart <<endl ;           // 这里竟然是 2734736
}


我 pentium d 的主频 2.8G, 程序输出结果竟然是 2734736, 应该是 280000000 左右才对. 请问这是怎么回事?

21 个解决方案

#1


没问题,这边返回的不是真正的cpu 频率
是操作系统内部cpu timer的频率,也就是软件的精度

#2


别的计算机就有可能返回 280000000 了么?

#3


引用 2 楼 walfud 的回复:
别的计算机就有可能返回 280000000 了么?

很难有

#4


这是高精度性能计时器的频率,不是cpu的频率

windows下,cpu的标称频率在这里
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\~MHz

#5


楼上说的标称跟 QueryPerformanceFrequency 无关.

#6


引用 5 楼 walfud 的回复:
楼上说的标称跟 QueryPerformanceFrequency 无关.


什么意思?

你要想获得cpu频率,或者查注册表查bios(标称的),或者现场计算(实际的),粗略计算(忽略了很多问题)看下例

高精度性能计数器的频率是不变的,否则就达不到计时的效果了,而且比cpu(平均)频率低得多

与cpu频率直接对应的是时戳计数器(实际上不能计时,说时戳其实名不副实),rdtsc。我的机子上,高精度性能计数器实际上也是要用rdtsc实现,只不过系统做了调整使之能成为计时器,所以必然比时戳计数器慢得多

#define read_tsc(tsc) \
long long tsc; \
_asm rdtsc \
_asm mov dword ptr[tsc],eax \
_asm mov dword ptr[tsc+4],edx

#define read_hrpc(pc) \
LARGE_INTEGER pc; \
QueryPerformanceCounter(&pc);

int main()
{
read_hrpc(pc1);
read_tsc(tsc1);

cout <<"waiting..." <<endl;
Sleep(1000);

read_tsc(tsc2);
read_hrpc(pc2);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
double elapse=(pc2.QuadPart-pc1.QuadPart)/(double)freq.QuadPart;
double cpu_freq=(tsc2-tsc1)/elapse;

cout <<"perf freq:\t" <<freq.QuadPart/1000.0/1000 <<"\tMHz" <<endl;
cout <<"cpu freq:\t" <<cpu_freq/1000/1000/1000 <<"\tGHz" <<endl;

return 0;
}

#7


我这测了没问题。

#8


引用 7 楼 luciferisnotsatan 的回复:
我这测了没问题。


QueryPerformanceFrequency直接得到主频?

#10


系统属性里显示 2.53G

QueryPerformanceFrequency输出为 2527050000

#11


引用 10 楼 luciferisnotsatan 的回复:
系统属性里显示 2.53G
QueryPerformanceFrequency输出为 2527050000


性能确实高啊

我的cpu也是2.53,但perf频率低:

waiting...
perf freq:      2.46779 MHz
cpu freq:       2.52702 GHz
请按任意键继续. . .

#12


 9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

#13


引用 12 楼 walfud 的回复:
 9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

我记得以前在win7旗舰,64bit上测写的一段代码的执行时间,结果也是正确的,没差3个数量级。现在手上没win7系统,等下班回家后跑下看看。

#14


引用 13 楼 luciferisnotsatan 的回复:
引用 12 楼 walfud 的回复:

9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

我记得以前在win7旗舰,64bit上测写的一段代码的执行时间,结果也是正确的,没差3个数量级。现在手上没win7系统,等下班回家后跑下看看。


等你结果了

#15


win7上还真缩小了1k,QueryPerformanceCounter同样缩了1K,所以我那个花费的时间算出来还是对的。

#16


MSDN网站上搜了下,也没见有什么说明。函数说明还是in counts per second,没带k。

#17


经正版 win 7 x64 鉴定, win 7 会导致 QueryPerformanceFrequency 结果少了 3 个数量级.
结题.

#18


引用 17 楼 walfud 的回复:
经正版 win 7 x64 鉴定, win 7 会导致 QueryPerformanceFrequency 结果少了 3 个数量级.
结题.


发现你俩挺迷信高的数值 :)

这个api本来就没说一定是多少数量级,更没说一定和cpu标称频率接近

xp上那种直接返回cpu标称频率的,不大可能是精确可计时的,因为cpu频率是会变的,不要迷信这个值

xp没有公布足够的细节,但是从原理上即可以判断用cpu频率计时有问题,只不过一般用用没问题罢了

这个链接 http://support.microsoft.com/kb/895980
说明windows是看情况取一个计数器(或者也的确是计时器)做为QPC,而且可以指定

当然win7多核下的QPC返回值也不见得真的可靠,但至少没高得那么赤裸裸,“缩水”了不见得是坏事

#19


QueryPerformanceFrequency() 这货确实不是CPU频率,我的I5 CPu 2.8GHz
得到的值为3579545   才3.5M...Xp系统( 32 位) 

#20


引用 3 楼 agoago_2009 的回复:
[Quote=引用 2 楼 walfud 的回复:]

别的计算机就有可能返回 280000000 了么?

很难有

测试过了 XP window2003 window2008是可以的 虽然不一定 等于280000000 但肯定是相差不大 且是同一个数量级  但是到了win7 和win8 结果就完全不会了  会差偏小1000倍

#21


引用 6 楼 yisikaipu 的回复:
[Quote=引用 5 楼 walfud 的回复:]楼上说的标称跟 QueryPerformanceFrequency 无关.


什么意思?

你要想获得cpu频率,或者查注册表查bios(标称的),或者现场计算(实际的),粗略计算(忽略了很多问题)看下例

高精度性能计数器的频率是不变的,否则就达不到计时的效果了,而且比cpu(平均)频率低得多

与cpu频率直接对应的是时戳计数器(实际上不能计时,说时戳其实名不副实),rdtsc。我的机子上,高精度性能计数器实际上也是要用rdtsc实现,只不过系统做了调整使之能成为计时器,所以必然比时戳计数器慢得多

#define read_tsc(tsc) \
long long tsc; \
_asm rdtsc \
_asm mov dword ptr[tsc],eax \
_asm mov dword ptr[tsc+4],edx

#define read_hrpc(pc) \
LARGE_INTEGER pc; \
QueryPerformanceCounter(&pc);

int main()
{
read_hrpc(pc1);
read_tsc(tsc1);

cout <<"waiting..." <<endl;
Sleep(1000);

read_tsc(tsc2);
read_hrpc(pc2);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
double elapse=(pc2.QuadPart-pc1.QuadPart)/(double)freq.QuadPart;
double cpu_freq=(tsc2-tsc1)/elapse;

cout <<"perf freq:\t" <<freq.QuadPart/1000.0/1000 <<"\tMHz" <<endl;
cout <<"cpu freq:\t" <<cpu_freq/1000/1000/1000 <<"\tGHz" <<endl;

return 0;
}

这个不错  帮我解决问题

#1


没问题,这边返回的不是真正的cpu 频率
是操作系统内部cpu timer的频率,也就是软件的精度

#2


别的计算机就有可能返回 280000000 了么?

#3


引用 2 楼 walfud 的回复:
别的计算机就有可能返回 280000000 了么?

很难有

#4


这是高精度性能计时器的频率,不是cpu的频率

windows下,cpu的标称频率在这里
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\~MHz

#5


楼上说的标称跟 QueryPerformanceFrequency 无关.

#6


引用 5 楼 walfud 的回复:
楼上说的标称跟 QueryPerformanceFrequency 无关.


什么意思?

你要想获得cpu频率,或者查注册表查bios(标称的),或者现场计算(实际的),粗略计算(忽略了很多问题)看下例

高精度性能计数器的频率是不变的,否则就达不到计时的效果了,而且比cpu(平均)频率低得多

与cpu频率直接对应的是时戳计数器(实际上不能计时,说时戳其实名不副实),rdtsc。我的机子上,高精度性能计数器实际上也是要用rdtsc实现,只不过系统做了调整使之能成为计时器,所以必然比时戳计数器慢得多

#define read_tsc(tsc) \
long long tsc; \
_asm rdtsc \
_asm mov dword ptr[tsc],eax \
_asm mov dword ptr[tsc+4],edx

#define read_hrpc(pc) \
LARGE_INTEGER pc; \
QueryPerformanceCounter(&pc);

int main()
{
read_hrpc(pc1);
read_tsc(tsc1);

cout <<"waiting..." <<endl;
Sleep(1000);

read_tsc(tsc2);
read_hrpc(pc2);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
double elapse=(pc2.QuadPart-pc1.QuadPart)/(double)freq.QuadPart;
double cpu_freq=(tsc2-tsc1)/elapse;

cout <<"perf freq:\t" <<freq.QuadPart/1000.0/1000 <<"\tMHz" <<endl;
cout <<"cpu freq:\t" <<cpu_freq/1000/1000/1000 <<"\tGHz" <<endl;

return 0;
}

#7


我这测了没问题。

#8


引用 7 楼 luciferisnotsatan 的回复:
我这测了没问题。


QueryPerformanceFrequency直接得到主频?

#9


#10


系统属性里显示 2.53G

QueryPerformanceFrequency输出为 2527050000

#11


引用 10 楼 luciferisnotsatan 的回复:
系统属性里显示 2.53G
QueryPerformanceFrequency输出为 2527050000


性能确实高啊

我的cpu也是2.53,但perf频率低:

waiting...
perf freq:      2.46779 MHz
cpu freq:       2.52702 GHz
请按任意键继续. . .

#12


 9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

#13


引用 12 楼 walfud 的回复:
 9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

我记得以前在win7旗舰,64bit上测写的一段代码的执行时间,结果也是正确的,没差3个数量级。现在手上没win7系统,等下班回家后跑下看看。

#14


引用 13 楼 luciferisnotsatan 的回复:
引用 12 楼 walfud 的回复:

9 楼同学请别耽误别人时间.
10 楼兄弟, 我以前每次使用 QueryPerformanceFrequency 都是大概这个数量级, 但是这次 win 7 怎么一下子差了 3 个数量级呢?

我记得以前在win7旗舰,64bit上测写的一段代码的执行时间,结果也是正确的,没差3个数量级。现在手上没win7系统,等下班回家后跑下看看。


等你结果了

#15


win7上还真缩小了1k,QueryPerformanceCounter同样缩了1K,所以我那个花费的时间算出来还是对的。

#16


MSDN网站上搜了下,也没见有什么说明。函数说明还是in counts per second,没带k。

#17


经正版 win 7 x64 鉴定, win 7 会导致 QueryPerformanceFrequency 结果少了 3 个数量级.
结题.

#18


引用 17 楼 walfud 的回复:
经正版 win 7 x64 鉴定, win 7 会导致 QueryPerformanceFrequency 结果少了 3 个数量级.
结题.


发现你俩挺迷信高的数值 :)

这个api本来就没说一定是多少数量级,更没说一定和cpu标称频率接近

xp上那种直接返回cpu标称频率的,不大可能是精确可计时的,因为cpu频率是会变的,不要迷信这个值

xp没有公布足够的细节,但是从原理上即可以判断用cpu频率计时有问题,只不过一般用用没问题罢了

这个链接 http://support.microsoft.com/kb/895980
说明windows是看情况取一个计数器(或者也的确是计时器)做为QPC,而且可以指定

当然win7多核下的QPC返回值也不见得真的可靠,但至少没高得那么赤裸裸,“缩水”了不见得是坏事

#19


QueryPerformanceFrequency() 这货确实不是CPU频率,我的I5 CPu 2.8GHz
得到的值为3579545   才3.5M...Xp系统( 32 位) 

#20


引用 3 楼 agoago_2009 的回复:
[Quote=引用 2 楼 walfud 的回复:]

别的计算机就有可能返回 280000000 了么?

很难有

测试过了 XP window2003 window2008是可以的 虽然不一定 等于280000000 但肯定是相差不大 且是同一个数量级  但是到了win7 和win8 结果就完全不会了  会差偏小1000倍

#21


引用 6 楼 yisikaipu 的回复:
[Quote=引用 5 楼 walfud 的回复:]楼上说的标称跟 QueryPerformanceFrequency 无关.


什么意思?

你要想获得cpu频率,或者查注册表查bios(标称的),或者现场计算(实际的),粗略计算(忽略了很多问题)看下例

高精度性能计数器的频率是不变的,否则就达不到计时的效果了,而且比cpu(平均)频率低得多

与cpu频率直接对应的是时戳计数器(实际上不能计时,说时戳其实名不副实),rdtsc。我的机子上,高精度性能计数器实际上也是要用rdtsc实现,只不过系统做了调整使之能成为计时器,所以必然比时戳计数器慢得多

#define read_tsc(tsc) \
long long tsc; \
_asm rdtsc \
_asm mov dword ptr[tsc],eax \
_asm mov dword ptr[tsc+4],edx

#define read_hrpc(pc) \
LARGE_INTEGER pc; \
QueryPerformanceCounter(&pc);

int main()
{
read_hrpc(pc1);
read_tsc(tsc1);

cout <<"waiting..." <<endl;
Sleep(1000);

read_tsc(tsc2);
read_hrpc(pc2);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
double elapse=(pc2.QuadPart-pc1.QuadPart)/(double)freq.QuadPart;
double cpu_freq=(tsc2-tsc1)/elapse;

cout <<"perf freq:\t" <<freq.QuadPart/1000.0/1000 <<"\tMHz" <<endl;
cout <<"cpu freq:\t" <<cpu_freq/1000/1000/1000 <<"\tGHz" <<endl;

return 0;
}

这个不错  帮我解决问题