c - GCC优化对位操作的有效性

标签 c optimization assembly x86

以下是在 x86-64 上用 C 语言设置单个位的两种方法:

inline void SetBitC(long *array, int bit) {
   //Pure C version
   *array |= 1<<bit;
}

inline void SetBitASM(long *array, int bit) {
   // Using inline x86 assembly
   asm("bts %1,%0" : "+r" (*array) : "g" (bit));
}

将 GCC 4.3 与 -O3 -march=core2 结合使用选项,当与常量 bit 一起使用时,C 版本花费大约 90% 以上的时间 . (两个版本编译成完全相同的汇编代码,除了 C 版本使用 or [1<<num],%rax 指令而不是 bts [num],%rax 指令)

与变量一起使用时 bit ,C 版本的性能更好,但仍然明显慢于内联汇编。

重置、切换和检查位具有相似的结果。

为什么 GCC 对这种常见操作的优化如此糟糕?我在 C 版本上做错了吗?

编辑: 抱歉让您久等了,这是我用来进行基准测试的代码。它实际上是从一个简单的编程问题开始的……

int main() {
    // Get the sum of all integers from 1 to 2^28 with bit 11 always set
    unsigned long i,j,c=0;
    for (i=1; i<(1<<28); i++) {
        j = i;
        SetBit(&j, 10);
        c += j;
    }
    printf("Result: %lu\n", c);
    return 0;
}

gcc -O3 -march=core2 -pg test.c
./a.out
gprof
with ASM: 101.12      0.08     0.08                             main
with C:   101.12      0.16     0.16                             main

time ./a.out也给出了类似的结果。

最佳答案

Why does GCC optimize so poorly for such a common operation?

前言:自 20 世纪 80 年代末以来,对编译器优化的关注已经从关注单个操作的微基准测试转移到 macrobenchmarks它专注于人们关心速度的应用程序。如今,大多数编译器编写者都专注于宏基准测试,开发良好的基准套件是一件很认真的事情。

回答:gcc 上没有人使用基准测试,其中 orbts 之间的差异对实际程序的执行时间很重要.如果你能制作这样的程序,你可能会引起 gcc-land 的人们的注意。

Am I doing something wrong with the C version?

不,这是非常好的标准 C。事实上,非常可读和惯用。

关于c - GCC优化对位操作的有效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2039592/

相关文章:

c - 循环的时间复杂度

c - 共享库函数什么时候加载到堆中?

c++ - C++ 和汇编程序之间的 Scanf 函数

assembly - x64 - 为什么仍然使用 'call' ?

c++ - 我可以写入嵌入式资源文本文件吗?

java - 用于游戏编程的 C 与 Java

php - 如何有效获取匹配的 Amazon S3 文件列表?

多变量的 Python 最小二乘法

c - C代码优化

gcc - 用gcc/mingw编译intel程序集