【发布时间】:2020-05-26 22:01:25
【问题描述】:
following question 是相关的,但答案是旧的,用户 Marc Glisse 的评论表明,自 C++17 以来有新的方法可以解决这个问题,但可能没有得到充分讨论。
我正在尝试让对齐内存为 SIMD 正常工作,同时仍然可以访问所有数据。
在 Intel 上,如果我创建一个 __m256 类型的浮点向量,并将我的大小减少 8 倍,它会给我对齐内存。
例如std::vector<__m256> mvec_a((N*M)/8);
我可以用一种有点笨拙的方式将指向向量元素的指针转换为浮点数,这样我就可以访问单个浮点值。
相反,我希望有一个正确对齐的 std::vector<float>,因此可以加载到 __m256 和其他 SIMD 类型中而不会出现段错误。
我一直在调查aligned_alloc。
这可以给我一个正确对齐的 C 样式数组:
auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));
但是我不确定如何为std::vector<float> 执行此操作。将 marr_a doesn't seem to be possible 的所有权授予 std::vector<float>。
我看到了一些建议我应该写一个custom allocator,但这似乎需要做很多工作,也许现代 C++ 有更好的方法?
【问题讨论】:
-
没有 segfaulting... 或者当您使用
_mm256_loadu_ps(&vec[i])时不会因缓存行拆分而导致潜在的减速。 (尽管请注意,使用默认调整选项,GCC splits not-guaranteed-aligned 256-bit loads/stores 进入 vmovups xmm / vinsertf128。因此,如果您关心代码在 GCC 上的编译方式,使用_mm256_load优于loadu如果有人忘记使用-mtune=...或-march=选项。) -
@PrunusPersica 你最终让它工作了吗?我也有同样的问题。如果您愿意,我们可以合作吗?
-
@gansub 我最终使用了
boost::alignment::aligned_allocator的代码。然后我可以用std::vector<T, aligned_allocator<float>>分配向量。它确实使普通的std::vectors与这种类型的对齐向量不直接兼容,但你总是可以写出绕过它的方法。
标签: c++ c++17 stdvector simd memory-alignment