2016-12-27 89 views
0

每当我打电话:std :: chrono反复调用QueryPerformanceFrequency?

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的时钟,我认为正确的方法是查询频率一次。

在微软的文档,它说:

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上。

谢谢。

+0

但是只有一个调用QueryPerformanceFrequency,第二个是哪里? – Rakete1111

+0

这看起来更像一个编译器特定的问题,而不是C++标准问题。 我建议你编辑你的标志,也许指定你使用的是什么编译器和版本(Visual Studio IDE可能使用不同的编译器)。 另外,因为我认为采用Visual C提供的C++库++是由微软生产的,它们可能* *知道最好的做法,用QueryPerformanceFrequency的()。 – roalz

+0

@Rakete它在循环中,我知道它每次都在循环中调用它。 – Zebrafish

回答

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的调用比对标准库实现的调用要快,因此它会替换相应的调用。

相关问题