c/c++ 编译器是否通过二的幂值将常量除法优化为移位?

2021-12-18 00:00:00 gcc optimization c c++

问题说明了一切.有谁知道以下是否...

Question says it all. Does anyone know if the following...

size_t div(size_t value) {
    const size_t x = 64;
    return value / x;
}

...优化成?

size_t div(size_t value) {
    return value >> 6;
}

编译器会这样做吗?(我的兴趣在于 GCC).是否存在可以执行和不执行的情况?

Do compilers do this? (My interest lies in GCC). Are there situations where it does and others where it doesn't?

我真的很想知道,因为每次我编写一个可以像这样优化的除法时,我都会花费一些精力去思考是否会浪费一秒钟的宝贵时间来做一个转换就足够的除法.

I would really like to know, because every time I write a division that could be optimized like this I spend some mental energy wondering about whether precious nothings of a second is wasted doing a division where a shift would suffice.

推荐答案

即使使用 g++ -O0(是的,-O0!),也会发生这种情况.您的函数编译为:

Even with g++ -O0 (yes, -O0!), this happens. Your function compiles down to:

_Z3divm:
.LFB952:
        pushq   %rbp
.LCFI0:
        movq    %rsp, %rbp
.LCFI1:
        movq    %rdi, -24(%rbp)
        movq    $64, -8(%rbp)
        movq    -24(%rbp), %rax
        shrq    $6, %rax
        leave
        ret

注意 shr??q $6,它是右移 6 位.

Note the shrq $6, which is a right shift by 6 places.

使用-O1,删除不必要的垃圾:

With -O1, the unnecessary junk is removed:

_Z3divm:
.LFB1023:
        movq    %rdi, %rax
        shrq    $6, %rax
        ret

在 g++ 4.3.3、x64 上的结果.

Results on g++ 4.3.3, x64.

相关文章