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

Does a c/c++ compiler optimize constant divisions by power-of-two value into shifts?(c/c++ 编译器是否通过二的幂值将常量除法优化为移位?)

本文介绍了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.

这篇关于c/c++ 编译器是否通过二的幂值将常量除法优化为移位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

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