编译器真的优化使这两个函数成为同一个程序集吗?
Does the compiler really optimize to make these two functions the same assembly?
我将其插入到 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();
}
Godbolt 输出是:
a():
movss xmm0, DWORD PTR .LC0[rip]
ret
b():
movss xmm0, DWORD PTR .LC0[rip]
ret
.LC0:
.long 1094268577
我不是装配专家,但我想知道这是否真的是真的,他们在做相同的工作。我什至看不到这个程序集中哪里有对 sqrt
的调用,或者 long
“常量”(?) 在那里做什么。
这个函数:
float a() {
A a{55,67,12};
return a.bar();
}
具有与此完全相同的可观察行为:
float a() {
return sqrt(55+67+12);
}
b()
也是如此。此外,sqrt(55+67+12) == sqrt(134) == 11.5758369028
.
Binary representation of the IEEE-754 floating point value 11.5758369028
is 01000001001110010011011010100001
. And that binary as integer is 1094268577
.
编译器应用所谓的 as if rule 将两个函数替换为具有与原始代码完全相同的可观察行为的程序集:两个函数 return a float
with value 11.5758369028
.
我将其插入到 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();
}
Godbolt 输出是:
a():
movss xmm0, DWORD PTR .LC0[rip]
ret
b():
movss xmm0, DWORD PTR .LC0[rip]
ret
.LC0:
.long 1094268577
我不是装配专家,但我想知道这是否真的是真的,他们在做相同的工作。我什至看不到这个程序集中哪里有对 sqrt
的调用,或者 long
“常量”(?) 在那里做什么。
这个函数:
float a() {
A a{55,67,12};
return a.bar();
}
具有与此完全相同的可观察行为:
float a() {
return sqrt(55+67+12);
}
b()
也是如此。此外,sqrt(55+67+12) == sqrt(134) == 11.5758369028
.
Binary representation of the IEEE-754 floating point value 11.5758369028
is 01000001001110010011011010100001
. And that binary as integer is 1094268577
.
编译器应用所谓的 as if rule 将两个函数替换为具有与原始代码完全相同的可观察行为的程序集:两个函数 return a float
with value 11.5758369028
.