gpt4 book ai didi

c++ - C++ 中转换为 simd 类型是未定义行为吗?

转载 作者:行者123 更新时间:2023-12-02 11:58:35 24 4
gpt4 key购买 nike

在 simd 教程中,我发现了以下代码片段。

void simd(float* a, int N)                                                                                                                                                                                        
{
// We assume N % 4 == 0.
int nb_iters = N / 4;
__m128* ptr = reinterpret_cast<__m128*>(a); // (*)

for (int i = 0; i < nb_iters; ++i, ++ptr, a += 4)
_mm_store_ps(a, _mm_sqrt_ps(*ptr));
}

现在我的问题是,带有 (*) 的行是否未定义行为?由于以下规范来自 ( https://en.cppreference.com/w/cpp/language/reinterpret_cast )

Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:

  • AliasedType and DynamicType are similar.
  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
  • AliasedType is std::byte, (since C++17)char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.

在这种情况下,如何防止未定义的行为?我知道我可以 std::memcopy,但性能损失会使 simd 无用,还是我错了?

最佳答案

编辑:请查看拷贝中的答案(和/或此处彼得的答案)。我下面写的内容在技术上是正确的,但在实践中并不真正相关。

<小时/>

是的,根据 C++ 标准,这将是未定义的行为。您的编译器仍可能将其作为扩展正确处理(因为 SIMD 类型和内在函数一开始就不属于 C++ 标准的一部分)。

为了安全、正确地执行此操作而不影响速度,您可以使用内部函数将 4 个 float 直接从内存加载到 128 位寄存器中:

__m128 reg = _mm_load_ps(a);

请参阅Intel Intrinsics Guide对于重要的对齐约束:

__m128 _mm_load_ps (float const* mem_addr)

Load 128-bits (composed of 4 packed single-precision (32-bit) floating-point elements) from memory into dst. mem_addr must be aligned on a 16-byte boundary or a general-protection exception may be generated.

关于c++ - C++ 中转换为 simd 类型是未定义行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58910969/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com