将矢量加载到大小不匹配的 AVX2 寄存器中

Load vector into AVX2 register with non matching size

假设我有一个双精度的 C++ std 向量,应该将其加载到 AVX2 寄存器中。这可以简单地通过使用 _mm256_load_pd(&vector1[0]) 命令来完成。
向量可以有任何大小,并且不能是 4 的倍数。如果向量大小不是 4 的倍数,现在加载剩余向量元素的最有效和高效的方法是什么?

将您的数组填充为可被 4 整除,这会浪费内存但会消除 if 语句和分支的低效率。

可以使用_mm256_maskload_pd指令。它需要第二个参数来指示要加载的值。

如果你想加载元素以进行逐元素操作(然后将它们存储回相同或另一个向量),一个简单的解决方案是使用重叠 loads/stores.

简化示例(如果vect.size()<4需要特殊处理)

// load last four elements for later use
__m256d last_input = _mm256_loadu_pd(vect.data()+vect.size()-4);
for(size_t i=0; i<vect.size()-4; i+=4) { // main loop
  __m256d input = _mm256_loadu_pd(vect.data()+i);
  _mm256_storeu_pd(some_operation(input), output.data()+i);
}
// process and store last elements (possibly overlapping with previous store):
_mm256_storeu_pd(some_operation(last_input, output.data()+vect.size()-4);

确保使用优化进行编译,并在 gcc/clang 上使用 -march=native(否则未对齐的 loads/stores 可能无法有效地拆分)。