【发布时间】:2021-03-22 09:46:07
【问题描述】:
*(B*)(&A) 和 (B)A 有什么区别
我正在使用 simd 代码。但我遇到了问题。
我无法将自己的 vector4 类型转换为 __m128
所以我确实喜欢这个
这很好用
#define XMM128Float(VECTOR4FLOAT) *(__m128*)(&VECTOR4FLOAT)
Vector4<float> vec4{};
XMM128Float(&vec4) = _mm_mul_ps(XMM128Float(*this), XMM128Float(*this));
我想知道为什么(__m128)vec4 不起作用....
它们之间有什么区别。
#define XMM128Float(VECTOR4FLOAT) *(__m128*)(&VECTOR4FLOAT)
template <>
[[nodiscard]] inline SIMD_CONSTEXPR auto Vector<4, float>::sqrMagnitude() const noexcept
{
Vector<4, float> Result;
XMM128Float(Result) = _mm_mul_ps(XMM128Float(*this), XMM128Float(*this));
return Result.x + Result.y + Result.z + Result.w;
}
我这样写了我的 SIMD 函数。
我正在使用 MS BUILD 16 编译器
【问题讨论】:
-
其中一个是明确定义的:D
-
@M.M:与人们可能猜到的不同(根据正常的 C++ 严格别名规则),定义明确的是指针转换:Is `reinterpret_cast`ing between hardware SIMD vector pointer and the corresponding type an undefined behavior?。尽管在 MSVC 中,指针转换类型的双关语总是定义明确的(只要您不读取数组或结构之外的内容):MSVC 就像
gcc -fno-strict-aliasing。 -
@PeterCordes Re“在 MSVC 指针转换类型中,双关语总是明确定义的”:这是官方记录的吗?用
-Ox(最大优化)编译时也是这样吗? -
@njuffa:是的,但我现在找不到。我很确定我已经看过 MSDN 文档,其中建议执行
reinterpret_cast<float&>(my_unsigned)或等效*(float*)&my_unsigned之类的操作。开发人员也广泛接受 MSVC 不会破坏严格的别名,并且他们无法在不破坏现有代码的情况下引入基于类型的别名优化,但正如我所说,我认为 MS 确实接受了这些习惯用法。 (也许是用不可移植的代码将人们锁定在他们的编译器中,或者让 GCC/clang 在“破坏他们的代码”时看起来很糟糕?) -
@PeterCordes 作为一名退休的软件工程师,我的 0.02 美元,他的整个职业生涯都在行业中:总的来说(除了例外)企业尽量不使现有客户的代码库失效。除此之外,有时他们会竭尽全力保持损坏的客户代码正常工作。在 Microsoft 的案例中,其中一些客户可能是内部客户。开源项目很少以类似的方式受到限制,并且直截了当地指导用户修复他们的非标准兼容代码(我发现自己曾经处于接收端,使用 gcc:已使用近 20 年的代码中的有符号整数溢出年)。