仅在发布模式下将 __m256i 存储在 std::vector 中会产生访问冲突[重复]

Posted

技术标签:

【中文标题】仅在发布模式下将 __m256i 存储在 std::vector 中会产生访问冲突[重复]【英文标题】:store __m256i in std::vector yields access violation only in release mode [duplicate] 【发布时间】:2016-07-08 12:49:03 【问题描述】:

在快速尝试中,我尝试将 AVX2 数据(类型 __m256i)存储在向量中:

__m256i values= _mm256_set_epi32(2, 4, 6, 8, 10, 12, 14, 16);

std::vector< __m256i > vecValues;

for ( int k = 0; k < static_cast< int >(100); k++ )

    vecValues.push_back( values);

使用 VS2012,这在调试模式下工作,但在发布模式下运行时会出现“未处理的异常/访问冲突”。

有人能解释一下,为什么以及如何正确存储数据吗?

【问题讨论】:

也许你的变量没有正确对齐? 而且即使你能做到这一点,它也没有任何意义。 @harold 我在完全围绕 SIMD 类型设计的例程中经常做这种事情(作为原始数组,而不是 std::vector)。 【参考方案1】:

__m256i 类型保证在为堆栈上的值分配空间时会遵守特定的对齐方式。但是,当您将它们放在std::vector 中时,该对齐注释将被忽略*。您将需要使用符合对齐要求的自定义分配器。这可能涉及使用 _mm_malloc 内在函数或在 MSVC 中调用 _aligned_malloc

__m256i 需要 32 字节对齐,因为它代表 256 位 AVX2 寄存器。默认情况下,MSVC 只为您提供 8 字节对齐(对于 32 位构建)或 16 字节对齐(对于 64 位构建),这是不够的。当您尝试运行构建时,这会导致访问冲突崩溃。

Donny-Dont has shared a Gist 提供了一个示例,说明如何编写自定义对齐感知分配器以将 SIMD 类型存储在 STL 容器中。您应该根据自己的目的进行调整。更多例子可以在this Stack Overflow question的回复中找到。

* GCC 将为此发出编译时警告:warning: ignoring attributes on template argument '__m256i aka __vector(4) long long int' 如果您使用-Wignored-attributes 选项(-Wall 隐含)。但是,我在 Clang 中没有看到这样的警告。

【讨论】:

以上是关于仅在发布模式下将 __m256i 存储在 std::vector 中会产生访问冲突[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将 __m256i 存储为整数

将 __m256i 设置为两个 __m128i 值的值

将 __m256i 设置为两个 __m128i 值的值

加载指令与 AVX 中的 AVX2 __m256i const* mem_addr [关闭]

有符号 32 位元素的 AVX __m256i 整数除法

多维 __m256i 数据类型对齐问题