如何向编译器指示数据已对齐?

问题描述 投票:0回答:1

考虑到包装

shared_ptr
std::span
的代码以获得额外的类型安全性:

template <size_t L>
class Vector {
 public:
  auto begin() { std::begin(data_); }
  auto end() { std::end(data_); }
  float* data() { return data_.data(); }
  float& operator[](size_t index) { return data_[index]; }
  size_t size() const { return L; }

 private:
  // Making sure it does not go away while vector exists
  std::shared_ptr<Store> store_;
  // Range in the Store where the vector data lives,
  // Address is 32 byte-aligned
  std::span<float, L> data_;
};

假设存在如下循环(

v1
v2
v3
是相同长度的向量):

for (size_t i = 0; i < v1.size(); ++i) {
    v3[i] = v1[i] + v2[i];
}

auto it1 = v1.begin();
auto it2 = v2.begin();
auto it3 = v3.begin();
while (it1 != v1.end()) {
    *it3 = (*it1++) + (*it2++);
}

我想向编译器表明矢量数据已针对 AVX2 指令进行对齐,但我不想编写 SIMD 代码(因为这也将为 ARM 和 WebAssembly 进行编译)。

指示对齐的最佳方式是什么?

c++ optimization simd memory-alignment
1个回答
0
投票

根据 Jérôme Richard 的评论,您可以使用

std::assume_aligned
来实现此目的;只需在返回指针的函数中调用它,即可让优化器清楚地知道它自设置以来没有更改:

auto begin() { 
  auto ret=std::begin(data_);
  std::assume_aligned<32>(&*ret);
  return ret;
}
float* data() {
  return std::assume_aligned<32>(data_.data());
}

第二个版本可能比第一个版本优化得更好,因为它可以使用

std::assume_aligned
的实际返回值;也许也可以在
std::span
中创建一个新的
begin
来使用它。

© www.soinside.com 2019 - 2024. All rights reserved.