用 std::chrono 计算持续时间在需要很长时间时给出 0 纳秒
Posted
技术标签:
【中文标题】用 std::chrono 计算持续时间在需要很长时间时给出 0 纳秒【英文标题】:counting duration with std::chrono gives 0 nanosecond when it should take long 【发布时间】:2016-10-02 22:19:09 【问题描述】:我试图使用 std::chrono 计算 for 循环所花费的持续时间,但即使我通过增加边界值使循环花费更长的时间,它也会给出 0 纳秒,这是代码:
#pragma pack(1) // dont align let's let it take longer
struct Foo
int x;
char c;
int z;
;
void take_time()
Foo f;
auto t1 = std::chrono::system_clock::now();
register int c = 0;
int x=0,y=0,z=1;
for (c=0;c<10000;c++) // even if i put 1000000000 it will take 0 nanosec !!!!!
f.z = x+y;
f.z += z-x+y;
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
输出:
token time : 0
但是当我将循环计数器的边界增加到非常非常大的值时,它突然需要永远! ,如果我输入 c
答案: 正如 WhiZTiM 所说,编译器正在删除循环,因为它没有任何用处(感谢 gcc asm("") ,一个空的 asm ,在循环中的任何地方。这将告诉编译器有一些他无法优化的低级操作! ,或者我们可以对循环中使用的任何变量使用 volitile 关键字,以防止编译器执行与该变量相关的任何优化。谢谢大家,希望对你有帮助
【问题讨论】:
x、y 和 z 未初始化。未定义的行为。 我后来添加了它们,现在它们已初始化但问题仍然存在! 【参考方案1】:首先,使用初始化变量是a sin.
优化器肯定发现循环是无用的(真的,循环中x
、y
、z
的值应该是什么);并且没有使用循环的结果(没有副作用),因此它在生成的代码中删除了循环。
void take_time()
Foo f;
auto t1 = std::chrono::system_clock::now();
register int c = 0;
int x,y,z;
///// Result not used
for (c=0;c<10000;c++) // even if i put 1000000000 it will take 0 nanosec !!!!!
f.z = x+y;
f.z += z-x+y;
/// We can discard the above
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
顺便说一句,register
关键字已被弃用。
对于 GCC 和 clang,有一种方法可以“吓跑”优化器,使其无法优化某些变量的使用。我使用这个功能:
template<typename T>
void scareTheOptimizer(T& x)
asm volatile("" :: "p"((volatile void*)&x) : "memory");
因此,当您在循环中调用它时,您现在应该会看到一些时间。
void take_time()
Foo f;
auto t1 = std::chrono::system_clock::now();
int c = 0;
int x=0,y=0,z=1;
for (c=0;c<10000;c++)
f.z = x+y;
scareTheOptimizer(f.z); /// <---- Added Here
f.z += z-x+y;
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
看Live On Coliru
【讨论】:
是的,我也是这么想的 :),令人惊叹的 gcc 太棒了 XD,我后来添加了 x,y,z 变量,它们不是原因,现在它们已被初始化,但事实并非如此改变什么,能不能举个不能忽视的循环例子? 谢谢,我们也可以使用volatile int c;
作为循环计数器,这样可以防止编译器进行任何与之相关的优化
我编辑了问题,我在最后附加了答案,你会发现很多信息以上是关于用 std::chrono 计算持续时间在需要很长时间时给出 0 纳秒的主要内容,如果未能解决你的问题,请参考以下文章
std::chrono::duration_cast - 比纳秒更精确的单位?
C++ 11 时间编程 std::chrono::steady_clock使用--计算程序执行时间