使用std::chrono计算持续时间,当它应该花费很长时间时,结果是0纳秒
counting duration with std::chrono gives 0 nanosecond when it should take long
我试图使用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<100000000,它需要0纳秒,但如果我在右边加一个"0",它需要永远!!
答案:正如WhiZTiM所说,编译器正在删除循环,因为它没有做任何有用的事情(感谢gcc <3),但我们真的不希望这种情况发生,当我们在测试算法时,看看哪一个在不同的编译器上更快(而不是这个特定的编译器),为此,我们可以插入asm行到循环中。asm("")
,一个空asm,在循环中的任何地方。这将告诉编译器,有一些低级操作是他无法优化的!或者,我们可以对循环中使用的任何变量使用volatile关键字,以防止编译器对该变量进行任何优化。谢谢大家,希望对大家有所帮助
首先,使用初始化的变量是错误的。
Optimizer明确指出循环是无用的(真的,循环中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
相关文章:
- 使用Boost Interprocess创建托管共享内存需要很长时间
- SFML RenderWindow打开窗口需要很长时间
- 为什么这个程序的结果是3 "born"?和 4 死
- 我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?
- Kafka C++客户端需要很长时间才能收到消息
- 给定使用 C++ 或 C,我如何测量在 linux 下进行线程切换需要多长时间?可能吗?
- asio::read() 需要很长时间,使用 asio::write 没有问题
- 为什么长 l = 0x80000000是正数?
- 分配给浮点数的积分文字除法 - 为什么结果是错误的?
- C++初始化的结果是什么?
- 我的输出结果是 0 英寸C++.可能是什么问题
- 将线程锁定很长时间
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 解决这个问题的时间复杂性是多少
- 即使长时间等待,C++线程也不会加入
- 连接() 在连接被拒绝时长时间挂起
- 对于大型C++项目,建议的 Eclipse CDT 配置是什么(索引器需要很长时间)
- 使用std::chrono计算持续时间,当它应该花费很长时间时,结果是0纳秒
- 对于长时间绘制密集粒子系统来说,什么是好的和安全的语言?
- 什么是长时间暂停exe的最佳方法