c - 不合逻辑的基准测试?

标签 c optimization loops benchmarking

我目睹了以下奇怪的行为。我有两个函数,它们的功能几乎相同 - 它们测量执行特定操作所需的周期数。在一个函数中,在循环内我递增一个变量;其他什么也没有发生。这些变量是不稳定的,因此它们不会被优化掉。这些是功能:

unsigned int _osm_iterations=5000;

double osm_operation_time(){
    // volatile is used so that j will not be optimized, and ++ operation
    // will be done in each loop
    volatile unsigned int j=0;
    volatile unsigned int i;
    tsc_counter_t start_t, end_t;
    start_t = tsc_readCycles_C();
    for (i=0; i<_osm_iterations; i++){
       ++j;
    }
    end_t = tsc_readCycles_C();
    if (tsc_C2CI(start_t) ==0 || tsc_C2CI(end_t) ==0 || tsc_C2CI(start_t) >= tsc_C2CI(end_t))
         return -1;
    return (tsc_C2CI(end_t)-tsc_C2CI(start_t))/_osm_iterations;
}

double osm_empty_time(){
    volatile unsigned int i;
    volatile unsigned int j=0;
    tsc_counter_t start_t, end_t;
    start_t = tsc_readCycles_C();
    for (i=0; i<_osm_iterations; i++){
        ;
    }
    end_t = tsc_readCycles_C();
    if (tsc_C2CI(start_t) ==0 || tsc_C2CI(end_t) ==0 || tsc_C2CI(start_t) >= tsc_C2CI(end_t))
        return -1;
    return (tsc_C2CI(end_t)-tsc_C2CI(start_t))/_osm_iterations;
}

那里有一些非标准功能,但我相信你会管理的。

问题是,第一个函数返回 4,而第二个函数(据说做得更少)返回 6,尽管第二个函数显然比第一个函数做得少一个。

这对任何人都有意义吗?

实际上,我创建了第一个函数,这样我就可以减少测量第二个函数的循环开销。您知道如何做到这一点吗(因为这种方法并不能真正解决问题)?

我使用的是 Ubuntu(我认为是 64 位)。

非常感谢。

最佳答案

我可以在这里看到一些东西。一是两个循环的代码看起来相同。其次,编译器可能会意识到变量i和变量j将始终具有相同的值并优化其中一个。您应该查看生成的程序集,看看到底发生了什么。

另一种理论是,对循环内部主体的更改影响了代码的可缓存性 - 这可能会将其跨缓存线或其他东西移动。

由于代码非常简单,您可能会发现很难获得准确的计时值,即使您进行了 5000 次迭代,您也可能会发现时间在您所使用的计时代码的误差范围内。现代计算机可能可以在不到一毫秒的时间内运行它 - 也许您应该增加迭代次数?

要在 gcc 中查看生成的程序集,specify the -S compiler option :

Q: How can I peek at the assembly code generated by GCC?

Q: How can I create a file where I can see the C code and its assembly translation together?

A: Use the -S (note: capital S) switch to GCC, and it will emit the assembly code to a file with a .s extension. For example, the following command:

gcc -O2 -S -c foo.c

will leave the generated assembly code on the file foo.s.

If you want to see the C code together with the assembly it was converted to, use a command line like this:

gcc -c -g -Wa,-a,-ad [other GCC options] foo.c > foo.lst

which will output the combined C/assembly listing to the file foo.lst.

关于c - 不合逻辑的基准测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/671848/

相关文章:

c - 错误: two or more data types in declaration specifiers

sql - Oracle:较小结果集的性能较差?

algorithm - 选择带分隔符的数字序列中第 i 个最小数的最佳方法

javascript - 遍历包含图像的数组并删除带有错误 Javascript 的图像

c# 遍历 ListView 项并通过单击按钮一次在文本框中显示一行

c - 如何从标准输入读取文本并使用低级文件处理将其写入文件?

c - 如何查找父进程的所有子进程(在 C 中)

c - For 循环在 C 中产生意外结果

c++ - C++ 库中的快速梯度下降实现?

Facebook iframe 应用程序的重定向循环问题