【问题标题】:Why does even a 16-byte aligned address cause _mm_load_si128 to cause access violation?为什么即使是 16 字节对齐的地址也会导致 _mm_load_si128 导致访问冲突?
【发布时间】:2014-05-17 20:30:50
【问题描述】:

以下在 MSVC 上编译时没有警告。

#include <iostream>
#include <emmintrin.h>

int main() 
{
    __declspec(align(16)) int x = 42;
    std::cout << &x << "\n";  // Print out the address that holds x

    __m128i v = _mm_load_si128((__m128i const*)(x));
}

基本上,代码对齐一个 32 位整数,并尝试将其加载到 __m128i 类型中。 _mm_load_si128 要求输入地址为 16 字节对齐。 _mm_loadu_si128 不需要它,但两者都会导致上述代码在运行时发出访问冲突。为什么,我该如何解决?

【问题讨论】:

    标签: c++ sse intrinsics


    【解决方案1】:

    你忘记取x的地址了:

    __m128i v = _mm_load_si128((__m128i const*)(&x));
    //                                          ^
    //                                          |
    //                     Here ----------------+
    

    此外,您没有为数据提供足够的空间,因此_mm_load_si128 最终会读取超过已分配内存块的末尾。

    【讨论】:

    • 更不用说 16 字节的加载不适合 int。
    • @PaulR 感谢您的精彩评论 - 我错过了那里的未定义行为!
    • @user3475799 根据规范,16字节对齐应该足够了。
    • @user3475799 您只需要为x 变量分配足够的空间。您可以将其设为四个 32 位 ints 的数组,如下所示:int x[4]; 请注意,现在您需要删除与号,因为 x 是一个数组,所以它的名称将被解释为一个指针在表达式中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多