Gug*_*ugi 7 c++ x86-64 compiler-optimization visual-c++ stdoptional
在对涉及 的代码进行基准测试时std::optional<double>,我注意到 MSVC 生成的代码的运行速度大约是 clang 或 gcc 生成的代码的一半。在花了一些时间减少代码后,我注意到 MSVC 显然在为std::optional::operator=. 使用std::optional::emplace()不会表现出速度减慢。
以下功能
void test_assign(std::optional<double> & f){
f = std::optional{42.0};
}
Run Code Online (Sandbox Code Playgroud)
产生
sub rsp, 24
vmovsd xmm0, QWORD PTR __real@4045000000000000
mov BYTE PTR $T1[rsp+8], 1
vmovups xmm1, XMMWORD PTR $T1[rsp]
vmovsd xmm1, xmm1, xmm0
vmovups XMMWORD PTR [rcx], xmm1
add rsp, 24
ret 0
Run Code Online (Sandbox Code Playgroud)
注意未对齐的 mov 操作。相反,函数
void test_emplace(std::optional<double> & f){
f.emplace(42.0);
}
Run Code Online (Sandbox Code Playgroud)
编译为
mov rax, 4631107791820423168 ; 4045000000000000H
mov BYTE PTR [rcx+8], 1
mov QWORD PTR [rcx], rax
ret 0
Run Code Online (Sandbox Code Playgroud)
这个版本更简单、更快。这些是使用 MSVC 19.32 和/O2 /std:c++17 /DNDEBUG /arch:AVX.
clang 14 与-O3 -std=c++17 -DNDEBUG -mavx产生
movabs rax, 4631107791820423168
mov qword ptr [rdi], rax
mov byte ptr [rdi + 8], 1
ret
Run Code Online (Sandbox Code Playgroud)
在这两种情况下。
替换std::optional<double>为
struct MyOptional {
double d;
bool hasValue; // Required to reproduce the problem
MyOptional(double v) {
d = v;
}
void emplace(double v){
d = v;
}
};
Run Code Online (Sandbox Code Playgroud)
表现出同样的问题。显然 MSVC 在增加bool成员方面遇到了一些麻烦。
请参阅godbolt的实例。
为什么 MSVC 会做出这些不一致的举动?即问题不在于为什么它们不对齐而不是对齐(根据这篇文章,这不会改善事情)。但为什么 MSVC 在赋值情况下会产生相当昂贵的指令集呢?这只是 MSVC 的一个错误(或者错过了优化机会)吗?或者我错过了什么?
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |