简单的for()循环基准测试与任何循环绑定

时间:2018-06-19 09:27:48

标签: c++ performance benchmarking microbenchmark

我愿意编写一个代码,让我的CPU执行一些操作,看看他花了多少时间来解决它们。我想做一个从i = 0到i <5000的循环,然后将i乘以一个常数和时间。我已经结束了这段代码,它没有错误,但即使我改变循环i&lt; 49058349083或者如果i&lt; 2它需要相同的时间,它也只需要0.024秒来执行代码。是什么错误?

PD:我昨天开始学习C ++我很抱歉,如果这是一个非常容易回答的问题,但我找不到解决方案

#include <iostream>
#include <ctime>

using namespace std;

int main () {
    int start_s=clock();

    int i;
    for(i=0;i<5000;i++){
        i*434243;
    }

    int stop_s=clock();
    cout << "time: "<< (stop_s-start_s)/double(CLOCKS_PER_SEC)*1000;

    return 0;
}

4 个答案:

答案 0 :(得分:4)

由于for循环的主体:

i*434243;

什么都不做,所以假设您正在编译启用了优化标志的代码,编译器会将其擦掉。

将其更改为:

int a = i*434243;

可能会在-O0以外的任何其他地方进行优化,所以我不建议。

此外,这将导致未定义行为,因为溢出,因为您使用的常量值相对较大,因为i继续递增。

我建议你这样做:

int a = i * i;
cout << a << "\n";   

答案 1 :(得分:2)

您编写的代码不是CPU正在执行的指令。简而言之:编译器将您的代码转换为可以是任何内容的机器指令,只要结果与执行您在代码中记下的确切步骤相同(通俗地称为“as-if”规则) )。考虑这个例子:

int foo() {
    int x = 0;
    for (int i=0;i<1000;i++){
        x += i;
    }
    return 42;
}

int bar() {
    return 42;
}

这两个函数看起来完全不同,但是,编译器可能会为它们创建完全相同的机器代码,因为您无法确定是否执行了额外的循环(烧毁CPU功率并且花费时间不计算对于as-if规则)。

编译器优化代码的积极程度由-O标志控制。通常-O0用于调试版本(因为它编译速度更快),-O2-O3用于版本构建。

时序代码可能很棘手,因为你必须确保实际上正在测量某些东西。对于foo,你可以通过写这个来确保执行循环(*):

int foo() {
    int x = 0;
    for (int i=0;i<1000;i++){
        x += i;
    }
    return x;
}

(*)=即使这样也不会导致在大多数编译器上运行循环,因为这种循环是一种常见的模式,它被检测到并导致x = 1000*1001/2;行的某些内容。

答案 2 :(得分:1)

通常很难让编译器保留您感兴趣的代码进行分析。

我强烈建议对实际代码进行分析,因为在根据大量单独的测量预测实际代码的时间时存在很多缺陷。

如果您希望继续,可以选择将变量声明为volatile并将其答案分配给它。

volatile int a = i * 434243;

另一种方法是创建一个函数并返回该值。您可能需要禁用内嵌。

你不太可能回答诸如“乘法多长时间?”之类的问题。你总是在回答这样一个问题:“做多少需要多长时间并给我答案?”。

您通常需要“保留临时数”并检查汇编程序以确保它正在执行您期望的操作。如果你正在调用一个函数,那么你可能想要比较调用一个不做任何尝试的函数,并从你的时间中消除调用开销。

答案 3 :(得分:0)

我稍微修改了您的代码如下:

#include <iostream>
#include <ctime>

using namespace std;

int main() {
    for (long long int j = 10000000; j <= 10000000000; j = j * 10) {

        int start_s = clock();

        for (long long int i = 0; i < j; i++) {
            i * 434243;
        }

        int stop_s = clock();

        cout << "time: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) * 1000 << endl;
    }

    int k;
    cin >> k;
    return 0;
}

输出:(这对我来说非常好。)

time: 23
time: 224
time: 2497
time: 21697

有一点需要注意。由于i是一个整数,所以它永远不会等于49058349083。在你的情况下,上限转换为int,它对应于-2,147,483,648和2,147,483,647之间的任何值,因此循环运行0到2,147,483,647次之间的任何值,这对于简单的乘法运算来说并不是那么大。 (对于49058349083,则为1813708827)。

尝试使用long long int,可以介于-2 ^ 63和2 ^ 63-1

之间