C++ 将数据存储在对齐数组的中间


#include<cstdint>
#include<iostream>
#include<immintrin.h>
using namespace std;
int main()
{
alignas(32) int32_t a[32];
__m256i t256(_mm256_setzero_si256());
_mm256_store_si256(reinterpret_cast<__m256i*>(a),t256);
cout<<"pass"<<endl;
_mm256_store_si256(reinterpret_cast<__m256i*>(a+8),t256);
cout<<"pass"<<endl;
_mm256_store_si256(reinterpret_cast<__m256i*>(a+4),t256);
cout<<"pass"<<endl;
}

在Windows中运行该程序时,我得到了三个"通过"(由vs2017 15.6.6编译,CPU为i7-6700HQ)。
但是,我在 arch linux 中运行第三条语句时Segmentation fault(由 g++ 7.3.1 和 clang 6.0.0 编译,CPU 为 i7-7820x)。
我使用的选项是-std=c++17 -march=native.

在我看来,我可以存储在a内的任何位置,因为a在 32 字节边界上对齐,每个元素都是 32 位整数。

但是我得到什么Segmentation fault
英特尔_mm256_store_si256

__m256i需要对齐到 32 字节(256 位)边界。由于数组a通过alignas(32)对齐到32字节边界,地址aa+8(等效于(char*)a + 8*sizeof(int32_t)地址)也对齐到32字节边界。

然而a+4不是。其地址将位于两个 32 字节边界之间。因此,您的第三条语句具有未定义的行为,并且可能会在不同的体系结构上执行不同的操作。

最新更新