使用std :: chrono进行计数的持续时间应该很长时会给出0纳秒 [英] counting duration with std::chrono gives 0 nanosecond when it should take long
问题描述
我试图使用std :: chrono计算for循环所花费的持续时间,但是即使我通过取消绑定值使循环花费更长的时间,它也提供了0纳秒的时间,这是代码:
I was trying to count the duration taken by a for loop using std::chrono but it gives 0 nanoseconds even if i make the loop take longer by increamenting the bound value , this is the code :
#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'则将永远花费!!
but when i increament the bound of the loop's counter to very very huge value it suddenly takes forever !! , if i put c<100000000 it takes 0 nanosec but if i add one '0' on the right it takes forever !!
答案:正如WhiZTiM所说的那样,编译器正在删除循环,因为它没有任何用处(感谢gcc< 3),但是我们真的不希望在测试算法时看到这种情况,以确保在不同的编译器上速度更快(和(不是这个特别的),为此,我们可以在循环中插入一个asm行. asm(")
,一个空的asm,在循环中的任何位置.这将告诉编译器有些无法优化的低级操作!,或者我们可以对循环中使用的任何变量使用volitile关键字,以防止编译器进行与该变量相关的任何优化.谢谢大家,我希望这对您有帮助
the answer :
as WhiZTiM said , the compiler is removing the loop because it does nothing useful ( thanks gcc <3 ) , but we really don't want that to happen when we are testing to algorithms to see wich one is faster on different compilers ( and not this spesific one ) , to do so we can insert an asm line into the loop . asm("")
, an empty asm , anywhere in the loop . That will tell the compiler that there is some low level operations that he can't optimize ! , or we can use the volitile keyword for any variable used in the loop that prevents the compiler from doing any optimization related to that variable . thanks everyone i hope this helps
推荐答案
First of all, using initialized variables is a sin.
Optimizer肯定发现循环是无用的(实际上,循环中 x
, y
, z
的值应该是什么);并且没有使用循环的结果(没有副作用),因此它在生成的代码中删除了循环.
The Optimizer definitely figured out the loop was useless(really, what should be the values of x
, y
, z
in the loop); and result of the loop wasn't used (no side effects), so it removed the loop in the generated code.
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;;
}
BTW,不推荐使用 register
关键字.
BTW, the register
keyword there is deprecated.
对于GCC和clang,有一种方法可以吓跑"优化器,以优化某些变量的使用.我使用此功能:
For GCC and clang, there's a way to "scare" the optimizer from optimizing out the use of certain variables. I use this function:
template<typename T>
void scareTheOptimizer(T& x){
asm volatile("" :: "p"((volatile void*)&x) : "memory");
}
因此,当您在循环中调用它时,您现在应该会看到一些计时.
So, when you call that in your loop, you should see some timing now.
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;;
}
这篇关于使用std :: chrono进行计数的持续时间应该很长时会给出0纳秒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!