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

注意 shrq $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++ 编译器是否通过二的幂值将常量除法优化为移位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Prevent class inheritance in C++(防止 C++ 中的类继承)
Why should I declare a virtual destructor for an abstract class in C++?(为什么要在 C++ 中为抽象类声明虚拟析构函数?)
Why is Default constructor called in virtual inheritance?(为什么在虚拟继承中调用默认构造函数?)
C++ cast to derived class(C++ 转换为派生类)
C++ virtual function return type(C++虚函数返回类型)
Is there any real risk to deriving from the C++ STL containers?(从 C++ STL 容器派生是否有任何真正的风险?)