【问题标题】:c++ store data in middle of an aligned arrayc ++将数据存储在对齐数组的中间
【发布时间】:2018-04-18 22:43:36
【问题描述】:
#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
Intel _mm256_store_si256

【问题讨论】:

  • __m256i 是否需要与 32 字节(256 位)边界对齐? a+4 不在 32 字节边界上。
  • @kevin 每个元素都是 32 位整数,所以 a+1 a+2 a+3 ... 也应该在 32 字节边界上对齐,不是吗?
  • 不,a+1 位于 32 位(4 字节)边界上。
  • @Kevin 我明白了,它是 32-byte 边界而不是 32-bit 边界。谢谢。

标签: c++ alignment intel


【解决方案1】:

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

但是a+4 不是。它的地址将在两个 32 字节边界之间。因此,您的第三个语句具有未定义的行为,并且可能在不同的架构上执行不同的操作。

【讨论】:

  • 在不同的编译器上,你的意思是。英特尔内在函数只能针对 x86 进行编译。但是是的,一些编译器使用vmovdqu(未对齐存储),即使源使用store 而不是storeu,以更加“宽容”。 (或者禁用您构建使用硬件对齐检查来检测潜在性能问题的版本的能力。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多