使用std :: chrono进行计数的持续时间应该很长时会给出0纳秒 [英] counting duration with std::chrono gives 0 nanosecond when it should take long

查看:73
本文介绍了使用std :: chrono进行计数的持续时间应该很长时会给出0纳秒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用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;;
}

在Coliru上直播

这篇关于使用std :: chrono进行计数的持续时间应该很长时会给出0纳秒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆