std :: chrono重复调用QueryPerformanceFrequency?

时间:2016-12-27 14:51:05

标签: c++ time std clock chrono

每当我打电话:

std::chrono::high_resolution_clock::now().time_since_epoch().count();

它的装配说明是:

std::chrono::high_resolution_clock::now().time_since_epoch().count();
00007FF7D9E11840  call        qword ptr [__imp__Query_perf_frequency (07FF7D9E14090h)]  
00007FF7D9E11846  call        qword ptr [__imp__Query_perf_counter (07FF7D9E140A0h)] 

之前我使用过Windows API时钟,我认为正确的方法是查询频率一次。

在Microsoft文档中,它说:

  

QueryPerformanceFrequency检索性能的频率   计数器。性能计数器的频率在系统中是固定的   启动并在所有处理器上保持一致。因此,频率   只需要在应用程序初始化时查询结果   可以缓存。

这是一个循环所以我认为对QueryPerformanceFrequency的调用是重复完成的。这是在发布模式下构建并使用/ O2优化。

此外,如果我构建在调试模式下,它会进行以下程序集:

std::chrono::high_resolution_clock::now().time_since_epoch().count();
00007FF774FC9D19  lea         rcx,[rbp+398h]  
00007FF774FC9D20  call        std::chrono::steady_clock::now (07FF774FB1226h)  
00007FF774FC9D25  lea         rdx,[rbp+3B8h]  
00007FF774FC9D2C  mov         rcx,rax  
00007FF774FC9D2F  call        std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000> > >::time_since_epoch (07FF774FB143Dh)  
00007FF774FC9D34  mov         rcx,rax  
00007FF774FC9D37  call        std::chrono::duration<__int64,std::ratio<1,1000000000> >::count (07FF774FB1361h) 

我不了解汇编,我不知道为什么在发布模式下调用Windows API,而在调试模式下没有提及它。另外,我在Visual Studio上。

感谢。

1 个答案:

答案 0 :(得分:1)

VS的优化器似乎没有把QueryPerformanceFrequency的调用放在循环之外。它没有认识到输出在第一次迭代后的每次迭代中总是相同的,因此它无法优化它,任何理智的优化器都会这样做:)

可能是一个缺少的功能或某些东西,而不是我认为的错误,正如我所说,VS优化了对循环外的foo的调用(此刻我无法访问VS) ,所以我无法测试):

int value = 0;
void foo() { value = 2; }

for (int i = 0; i < 10; ++i) {
    foo();
    std::cout << i * value << '\n';
}

没有调用QueryPerformance*函数的原因是在Debug中,优化器不允许优化。优化器发现对本机Windows API的调用比调用标准库实现更快,因此它取代了相应的调用。