仅在发布模式下将 __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 中会产生访问冲突[重复]的主要内容,如果未能解决你的问题,请参考以下文章