请考虑以下代码段:
class MyClass1{
public:
double value;
MyClass1 &operator*=(const MyClass1 &right){
value *= right.value;
return *this;
}
friend MyClass1 operator*(const MyClass1 &left, const MyClass1 &right){
auto result = left;
result *= right;
return result;
}
};
和
class MyClass2{
public:
double value;
MyClass2(double v) : value(v){}
MyClass2(){}
friend MyClass2 operator*(const MyClass2 &left, const MyClass2 &right){
return MyClass2 (left.value * right.value);
}
};
我感兴趣的是:常见的编译器知道,运算符MyClass1 :: operator *和MyClass2 :: operator *给出了相同的结果。如果设置说,有人希望“s”具有高度优化的可执行文件,他们还会制作相同的可执行文件吗?原则上他们也会这样做。
我读了它的“未经优化的”汇编代码(由Visual C ++制作),它们看起来不同。但性能优化的汇编代码非常庞大,复杂且(对我而言)难以理解。
在非优化版本中,第二个实现速度几乎是第一个实现速度的三倍。
答案 0 :(得分:2)
您的代码中存在更大的问题,但这是一个很好的在线服务,用于检查生成的程序集:
我会说在你知道如何使代码正确之前不要打扰优化是一个好主意。也就是说,如果一个不错的在线工具可以帮助你让烦恼得到休息,那就更好了!
喜欢aboe的截图是根据您的问题改编的。免责声明:它是固定的未定义行为(至少由于单位化值):
struct MyClass1{
double value;
MyClass1 &operator*=(MyClass1 const &right){
value *= right.value;
return *this;
}
friend MyClass1 operator*(MyClass1 const &left, MyClass1 const &right){
auto result = left;
result *= right;
return result;
}
};
class MyClass2{
public:
double value;
MyClass2(double v = 0.0) : value(v){}
friend MyClass2 operator*(MyClass2 const &left, MyClass2 const &right){
return left.value * right.value;
}
};
template <typename T> double test() {
T a,b;
volatile T c = a * b;
return c.value;
}
int main()
{
return test<MyClass1>() + test<MyClass2>();
}
使用clang 3.4 -O3 -march = corei7-avx在我的VM上进行此演示的相应程序集是:
.file "test.cpp"
.text
.globl main
.align 16, 0x90
.type main,@function
main: # @main
.cfi_startproc
# BB#0:
vmulsd %xmm0, %xmm0, %xmm0
vmovsd %xmm0, -8(%rsp)
vmovsd -8(%rsp), %xmm0
movq $0, -8(%rsp)
vaddsd -8(%rsp), %xmm0, %xmm0
vcvttsd2si %xmm0, %eax
ret
.Ltmp0:
.size main, .Ltmp0-main
.cfi_endproc
.ident "Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)"
.section ".note.GNU-stack","",@progbits