在发布模式下运行程序

时间:2015-12-12 11:36:05

标签: c++

我想测试大循环中某些代码的排序速度,例如1000000000次。 当我在调试模式下运行程序时,我看到了3.192秒的持续时间, 但在释放模式下,持续时间为0.000。我通过biger计数器测试,但它是0.000秒。 对于我用于计数器的每个更大的数字,例如在释放模式中的10000000000,此过程和结果是相等的 有什么问题?

我的代码是:

#include<time.h>
#include<iostream>

int main() {
    clock_t t1, t2;



double d1 = 97.9834;
double d2 = 897.9134;
double d3 = 0.0;

t1 = clock();
for (size_t i = 0; i < 1000000000; i++)
{
    d3 = d1 + d2;
}

t2 = clock();

char msg[100];
sprintf_s(msg, 100, "time is :%.3f\n", double(t2 - t1) / 1000.0);
cout << msg << endl;


return 0;
}

5 个答案:

答案 0 :(得分:2)

编译器需要生成优化代码,该代码表现为&#34; as-if&#34;除了执行时间之外,它没有做任何优化(除了一些例外,例如快速数学浮点优化)。您可以关闭优化,但之后您将无法测量优化代码。

问题的根源是,你无法衡量你想要衡量的东西,或者你已经得到了正确的结果(循环被优化掉了,应该如此)。但是,如果要强制编译器生成代码,则有一个关键字:volatile

volatile double d1 = 97.9834;
volatile double d2 = 897.9134;
volatile double d3 = 0.0;

现在需要编译器将变量放入内存,并且实际读取d1和d2的值,并将结果写入d3,当循环中的加法语句执行此操作时,循环迭代的次数。你只能使这些中的一个或两个变为volatile,因此编译器可以跳过一些代码或将非易失性变量保存在寄存器中,循环会更快。

在使这些变量变得易变之后,你会测量一些有用的东西,这取决于你实际想要测量的东西......

更多信息:C和C ++中volatile的目的是告诉编译器这个变量类似于内存映射的硬件寄存器,读取或写入它有一些外部效果,所以它永远不能被优化掉。它在PC程序中很少有用,尽管常见的误解与多线程编程无关(与Java中的不同)。

答案 1 :(得分:2)

你需要以某种方式隐藏优化器中操作的无用性。但是,由于您希望测量操作优化的时间长度,因此在说服优化器不要完全删除操作的过程中,您不希望破坏操作本身的优化。

如果d3 = d1 + d2; d3d1d2之一变为d3 = d1 + d2;,则d3 = d1 + d2;无法做多少事情,您可以阻止优化工具排除您想要衡量的工作,但是以增加一些您可能不想衡量的工作为代价。

在其他情况下,有更好的方法可以防止优化程序删除您要测量的内容。在较大的情况下,一种常见的方法是将关键部分放入不同的编译单元,以便优化器无法看到那部分。但在这种情况下,这样做的调用开销会比volatile的额外成本更糟糕。

如果问题是简化的&#34;为什么不测量发布时间&#34;并且你真的想要测量比return User::whereIn('id', [1, 2, 3]) ->whereLang($channel) ->get(); 更复杂的东西,你可能会更好地帮助询问你真正想要测量的东西。但如果目标确实是return User::whereIn('id', function () { return FooBar::whereFooId('u' . $user->id)->get(['users'])->toArray(); }) ->whereLang($lang) ->get(); 则没有答案。所花费的时间完全取决于它的使用方式,包括优化器看到它没用时需要零时间。

答案 2 :(得分:1)

我相信这个for循环已经在生产代码中进行了优化,因为它没有做任何有用的事情:你从不使用d3的值,为什么甚至计算它?

如果要执行此循环,请关闭优化(将-O0传递给编译器)。

答案 3 :(得分:1)

除了完全优化for循环外,clock()函数不是衡量时间的世界上最好的工具。对于初学者,你肯定想要做的是开始clock()刻度变化的测量(clock()刻度粒度相对较低,与高精度计数器相比)。请参阅CLOCKS_PER_SEC,例如在MSVC中仅为1000。在clock()刻度中间开始测量时,结果将非常不一致。

常见的模式是为了提高结果的一致性:

clock_t start;
const clock_t tmp = clock();
do {
    start = clock();
} while (tmp == start);

// execute the code

const clock_t end = clock();

答案 4 :(得分:1)

您必须利用性能测试结果来防止不必要的优化。一种方法是使变量'volatile':

#include<time.h>
#include<iostream>

volatile double d = 0;
int main() {
    clock_t t1 = clock();
    for (size_t i = 0; i < 1000000000; i++)
    {
        d = 0;
    }
    clock_t t2 = clock();
    std::cout << "time is " << t2 - t1 << std::endl;
    // Debug:   3474486
    // Release:  484208

    return 0;
}