当前位置: 首页 > 知识库问答 >
问题:

编译器是否真的进行了优化,使这两个函数成为同一个程序集?[重复]

邹修真
2023-03-14

我将其插入到Godbolt中,并惊喜地发现这两个函数调用a()b()-O0之外的任何情况下都是等价的(使用大多数主要编译器):

#include <cmath>

struct A {
    int a,b,c;
    float bar() {
        return sqrt(a + b + c);
    }
};

struct B {
    int a[3];
    float bar() {
        int ret{0};
        for (int i = 0; i<3; ++i) {
            ret += a[i];
        }
        return sqrt(ret);
    }
};

float a() {
    A a{55,67,12};
    return a.bar();
}

float b() {
    B b{55,67,12};
    return b.bar();
}

锁紧螺栓输出为:

a():
        movss   xmm0, DWORD PTR .LC0[rip]
        ret
b():
        movss   xmm0, DWORD PTR .LC0[rip]
        ret
.LC0:
        .long   1094268577

我不是组装专家,但我想知道这是否是真的,他们在做相同的工作。我甚至看不出在这个程序集中哪里有对sqrt的调用,或者long的“常量”(?)他在里面干什么。

共有1个答案

宋鸿
2023-03-14

此功能:

float a() {
    A a{55,67,12};
    return a.bar();
}

有着和这个完全一样的可观察行为:

float a() {
    return sqrt(55+67+12);
}

这同样适用于b()。此外,sqrt(556712)==sqrt(134)==11.5758369028

IEEE-754浮点值的二进制表示形式11.57583690280100000101110011010100001。作为整数的二进制数是1094268577

编译器应用了所谓的as if规则,用与原始代码具有完全相同的可观察行为的程序集替换这两个函数:这两个函数都返回一个值为11.5758369028浮点数

 类似资料:
  • 问题内容: 输出始终为。 但是,绝对可以使循环多次遍历1s 。 我认为,在闭包是在FUNC。 请参见下面的代码。 在多行“ +1”之后,输出正好是预期的很大数目。 问题答案: 记忆模型 2014年5月31日版本 介绍 Go内存模型指定了一种条件,在这种条件下,可以保证在一个goroutine中读取变量可以观察到在不同goroutine中写入同一变量所产生的值。 忠告 修改由多个goroutine同

  • 我想在中的包中使用功能,它有一个需求,作为

  • 问题内容: 我在观看NodeJS Interactive谈话时,那个家伙在说匿名函数的性能很差,原因之一是,如果它们没有名称,VM便无法根据使用频率来优化该函数,因为它没有名字。 因此,如果一个具有名称的函数被调用 可以优化为以下功能: 由于它是匿名的,无名的,因此不会进行优化。 所以我想知道箭头函数是否会做同样的事情,因为我认为您不能命名箭头函数。 将 被优化? 编辑:寻找该人提及此话题的谈话链

  • 假设我有一个RDD(50M记录/day redu),我想用几种不同的方式来总结。RDD记录是4元组:。 -布尔 ,,-0/1整数 我想数一下每个< code>foo有多少个 这将返回(在之后)一个列表,如。 问题是:有没有一种简单的方法可以避免扫描< code>rdd三次(对< code>foo 、< code>bar 、< code>baz各扫描一次)? 我的意思不是重写上面的代码来处理所有3个

  • 在最近的一个相关问题中,我发现以下代码 存在编译器错误,x不是init。(初始化)。令我惊讶的是,编译器无法推理init。尤其是因为这段代码似乎不需要任何运行时推理,如下所示: 在指示的第2行,被设置为。 第2行和第3行之间没有代码。 所以到达第3行,必然是所以init是不可避免的。 我不知道这是否正确。我隐约记得,编译器优化可以改变语句的执行顺序。这在这里起作用了吗?有没有可能在3号线和4号线之

  • 我正在使用英特尔SSE/AVX/FMA内部函数来实现一些数学函数的完美内联SSE/AVX指令。 给定以下代码 clang 3.9生成的程序集-march=x86-64-mfma-O3 虽然为sqrt生成的代码很好,但与std fma(依赖于编译器内部std::fma)相比,fma中存在不必要的VxORP(将绝对未使用的xmm3寄存器设置为零)和MOVS指令 GCC 6.2生成的程序集-march=