Ste*_*ler 5 c++ windows performance sleep
我最初在coderanch.com上询问过这个问题,所以如果你试图在那里帮助我,谢谢,并且不觉得有必要重复这些努力.但是,coderanch.com主要是一个Java社区,这看起来(经过一些研究后)确实是一个Windows问题,所以我和那里的同事认为这可能是寻找帮助的更合适的地方.
我写了一个简短的程序,要么在Windows性能计数器上旋转直到33ms,要么调用Sleep(33).前者没有表现出意想不到的效果,但后者似乎(不一致地)使后续处理减慢了大约40ms(或者说,或者对性能计数器返回的值有一定影响).在旋转或Sleep()之后,程序调用一个例程runInPlace(),它旋转2ms,计算它查询性能计数器的次数,并返回该数字.
当通过旋转完成最初的33ms延迟时,runInPlace()的迭代次数往往是(在我的Windows 10上,XPS-8700)大约250,000.它可能由于其他系统开销而变化,但它变化平滑约250,000.
现在,当通过调用Sleep()完成初始延迟时,会发生一些奇怪的事情.很多对runInPlace()的调用都会返回一个接近250,000的数字,但是其中相当一部分返回的数字接近50,000.同样,范围变化大约50,000,相当顺利.但是,它显然平均了一个或另一个,几乎没有返回80,000到150,000之间的任何回报.如果我在每次延迟后调用runInPlace()100次,而不是只调用一次,那么在20次调用之后,它永远不会在较小的范围内返回多次迭代.由于runInPlace()运行2ms,这意味着我观察到的行为在40ms后消失.如果我运行runInPlace()运行4ms而不是2ms,它在第10次调用之后永远不会返回较小范围内的迭代次数,因此,再次,行为在40ms后消失(同样如果runInPlace()运行仅1ms;在第40次通话后,行为消失了).
这是我的代码:
#include "stdafx.h"
#include "Windows.h"
int runInPlace(int msDelay)
{
LARGE_INTEGER t0, t1;
int n = 0;
QueryPerformanceCounter(&t0);
do
{
QueryPerformanceCounter(&t1);
n++;
} while (t1.QuadPart - t0.QuadPart < msDelay);
return n;
}
int _tmain(int argc, _TCHAR* argv[])
{
LARGE_INTEGER t0, t1;
LARGE_INTEGER frequency;
int n;
QueryPerformanceFrequency(&frequency);
int msDelay = 2 * frequency.QuadPart / 1000;
int spinDelay = 33 * frequency.QuadPart / 1000;
for (int i = 0; i < 100; i++)
{
if (argc > 1)
Sleep(33);
else
{
QueryPerformanceCounter(&t0);
do
{
QueryPerformanceCounter(&t1);
} while (t1.QuadPart - t0.QuadPart < spinDelay);
}
n = runInPlace(msDelay);
printf("%d \n", n);
}
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是使用Sleep()进行延迟时的一些典型输出:
56116 248936 53659 34311 233488 54921 47904 45765 31454 55633 55870 55607 32363 219810 211400 216358 274039 244635 152282 151779 43057 37442 251658 53813 56237 259858 252275 251099
这是我旋转创建延迟时得到的一些典型输出:
276461 280869 276215 280850 188066 280666 281139 280904 277886 279250 244671 240599 279697 280844 159246 271938 263632 260892 238902 255570 265652 274005 273604 150640 279153 281146 280845 248277
任何人都可以帮我理解这种行为吗?(注意,我在五台计算机上尝试过用Visual C++ 2010 Express编译的程序.它只在我拥有的两台最快的机器上显示这种行为.)
这听起来像是由于CPU在计算机不忙时运行的时钟速度降低(SpeedStep).当计算机空闲时(如在睡眠中),时钟速度将下降以降低功耗.在较新的CPU上,这可以是所列时钟速度的35%或更低.一旦计算机再次忙碌,在CPU再次加速之前会有一个小的延迟.
您可以关闭此功能(在BIOS中或通过将电源计划的高级设置中"处理器电源管理"下的"最低处理器状态"设置更改为100%.
除了@ 1201ProgramAlarm所说的(可能很好,现代处理器非常喜欢随时可以降频),它也可能是缓存预热问题.
当您要求休眠一段时间时,调度程序通常会为下一个CPU时间量程安排另一个线程/进程,这意味着相对于您的进程的高速缓存(指令高速缓存,数据高速缓存,TLB,分支预测器数据......)是当您的代码重新获得CPU时,将再次"冷".
| 归档时间: |
|
| 查看次数: |
277 次 |
| 最近记录: |