当前位置: 首页 > 面试题库 >

ac / c ++编译器是否将2的幂乘以常数来优化常数除法?

狄赞
2023-03-14
问题内容

问题说明了一切。有人知道以下内容吗?

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

…被优化成?

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

编译器会这样做吗?(我的兴趣在于GCC)。在某些情况下会这样做吗?在其他情况下却不会呢?

我真的很想知道,因为每次我写一个像这样可以优化的除法运算时,我都会花些精力思考是否浪费一秒钟宝贵的时间去做一个足以满足需要的除法运算。


问题答案:

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

_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位。

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

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

在g ++ 4.3.3,x64上的结果。



 类似资料:
  • 问题内容: Java编译器 或 JIT编译器是否通过恒定的2到位移位的幂来优化除法或乘法? 例如,以下两个语句是否被优化为相同? (基本上是这个问题,但对于Java) 问题答案: 不,Java编译器不会执行此操作,因为无法确定将显示什么符号。为什么这么重要?负整数上的位移产生与普通除法不同的结果。在这里,您可以看到一个演示:这个简单的测试: 另请注意,我使用代替。A 是无符号的移位,而A 是带符号

  • 根据这个问题,浮点除法与浮点乘法。由于某些原因,除法比乘法慢。 如果可能的话,编译器通常会用乘法代替除法吗? 例如: 会是: 如果它被认为是编译器可靠的问题,我使用的是VS2013默认编译器。但是,如果我得到一个通用的答案就好了(这种优化的理论有效性)

  • 有问题的代码如下: 编译器会优化它吗?根据C-Standard(如果我理解正确的话),第二个操作数必须提升为;因此乘法必须使用FPU(或fp仿真)完成。 从理论上讲,该操作可以在正常的硬件寄存器中完成,只需添加一个即时的(并且可能是溢出检查)。是否允许编译器执行此优化?是否有已知的编译器这样做?如果是这样,他们是否也会识别该表达式 这是避免有关隐式转换的静态代码检查器警告所必需的? 补充一下:我知

  • 我有以下一段代码: 我可以想象编译器具有消除函数中的子句所需的所有信息。调用该函数的唯一代码路径来自main,它接受,因此它应该能够确定该代码路径未被使用。但是: 在GCC 12.2中,我们看到第二部分链接到。 如果我函数,这将消失: 我在这里错过了什么?有没有办法让编译器做一些更智能的工作?这发生在带有 C 和 。

  • 本文向大家介绍C/C++ 编译器优化介绍,包括了C/C++ 编译器优化介绍的使用技巧和注意事项,需要的朋友参考一下 0. gcc -o gcc -o 的优化仍然是机械的,想当然的。只有做到深入理解计算机系统,加深对编程语言的理解,才能写出最优化的代码。 Linux下gcc 优化级别的介绍  · gcc -o0 ⇒ 不提供任何优化;  · gcc -o1 ⇒ 最基本的优化,主要对代码的分支、表达式、

  • “在Keras中,如果将模型的损失函数乘以某个常数C,并将学习率除以C,则训练过程中不会出现差异”,这是真的吗? 我有一个由Keras实现的模型。我将损失函数定义为: 在第一个场景中,我使用学习率等于0.005的Adam优化器,并且我用那个损失函数和优化器编译模型。我在一组训练数据上拟合该模型,并且我观察到它的损失在不到100个时期内从0.2下降到0.001。 在第二种情况下,我将损失函数改为: