c++ - MSVC 不良程序集生成
问题描述
在比较 MSVC、clang 和 GCC 中生成的程序集时。MSVC 程序集似乎比 Clang 代码差得多。
问题
在 GCC 和 MSVC 中是否有一个标志来产生等效的程序集,或者在这种特定情况下 Clang 是否更好。我尝试了各种 MSVC 标志(不同的 /O 标志),但没有发生实质性变化。
或者我的代码是否有变体,允许编译器实现更好的优化。我尝试在不丢失基本结构的情况下更改代码,也没有任何变化。
代码
我正在编译的代码只有 26 行,所以这里是:
#include <cstdint>
#include <type_traits>
template <typename A, typename B>
struct BitCast
{
static_assert(std::is_pod<A>(), "BitCast<A, B> : A must be plain old data type.");
static_assert(std::is_pod<B>(), "BitCast<A, B> : B must be plain old data type.");
static_assert(sizeof(A) == sizeof(B), "BitCast<A, B> : A and B must be the same size.");
static_assert(alignof(A) == alignof(B), "BitCast<A, B> : A and B must have the same alignment.");
//
union
{
A a;
B b;
};
//
constexpr BitCast(A const & value) noexcept : a{ value } {}
constexpr BitCast(B const & value) noexcept : b{ value } {}
//
operator B const & () const noexcept { return b; }
};
float XOR(float a, float b) noexcept
{
return BitCast<uint32_t, float>{ BitCast<float, uint32_t>{a} ^ BitCast<float, uint32_t>{b} };
}
我一直在 Godbolt 工作,以确定差异的原因https://godbolt.org/z/-VXqOT
带有“-std=c++1z -O3”的 Clang 9.0.0 产生了一个漂亮的:
XOR(float, float):
xorps xmm0, xmm1
ret
在我看来,这基本上是最佳的。
带有“-std=c++1z -O3”的 GCC 9.2 产生的效果稍差:
XOR(float, float):
movd eax, xmm1
movd edx, xmm0
xor edx, eax
movd xmm0, edx
ret
然后带有“/std:c++latest /O2”的 MSVC 产生了更糟糕的结果:
float XOR(float,float)
movss DWORD PTR $T1[rsp], xmm1
mov eax, DWORD PTR $T1[rsp]
movss DWORD PTR $T3[rsp], xmm0
xor eax, DWORD PTR $T3[rsp]
mov DWORD PTR $T2[rsp], eax
movss xmm0, DWORD PTR $T2[rsp]
ret 0
解决方案
推荐阅读
- arrays - ruby中哈希的重复键
- c++ - 如何理解scoped_lock的析构函数?cppreference会出错吗?
- indexing - solr 中的嵌套查询
- .net-core - 无法以其他用户身份恢复 nuget 包
- django - 使用 Jinga2 循环控制扩展
- javascript - 谷歌浏览器应用程序链接到另一个网站?清单 V3
- java - 索引缓慢或根本不再工作,直到重新启动
- javascript - 遍历数组并分配变量名称和id
- firebase - 如何使用 pyrebase 访问 Firebase 实时数据库中的根子节点
- swift - SwiftUI - 在父视图中堆叠多个方法调用