c - 矢量化 - SSE、AVX 和 AVX2 的预期加速

标签 c vectorization sse avx avx512

我正在使用以下 i7 处理器在 MacOS 上进行矢量化基准测试:

$ sysctl -n machdep.cpu.brand_string

Intel(R) Core(TM) i7-4960HQ CPU @ 2.60GHz

我的 MacBook Pro 是 2014 年年中的。

我尝试使用不同的标志选项进行矢量化:我感兴趣的 3 个是 SSE、AVX 和 AVX2。

对于我的基准测试,我添加了 2 个数组的每个元素并将总和存储在第三个数组中。

我必须让您注意到我正在为这些数组使用 double 类型。

以下是我的基准代码中使用的函数:

1*) 首先使用 SSE 矢量化:

#ifdef SSE
#include <x86intrin.h>
#define ALIGN 16
void addition_tab(int size, double *a, double *b, double *c)
{

 int i;
 // Main loop
 for (i=size-1; i>=0; i-=2)
 {
  // Intrinsic SSE syntax
  const __m128d x = _mm_load_pd(a); // Load two x elements
  const __m128d y = _mm_load_pd(b); // Load two y elements
  const __m128d sum = _mm_add_pd(x, y); // Compute two sum elements
  _mm_store_pd(c, sum); // Store two sum elements

  // Increment pointers by 2 since SSE vectorizes on 128 bits = 16 bytes = 2*sizeof(double)
  a += 2;
  b += 2;
  c += 2;
 }

}
#endif

2*) 其次是 AVX256 矢量化:

#ifdef AVX256
#include <immintrin.h>
#define ALIGN 32
void addition_tab(int size, double *a, double *b, double *c)
{

 int i;
 // Main loop
 for (i=size-1; i>=0; i-=4)
 {
  // Intrinsic AVX syntax
  const __m256d x = _mm256_load_pd(a); // Load two x elements
  const __m256d y = _mm256_load_pd(b); // Load two y elements
  const __m256d sum = _mm256_add_pd(x, y); // Compute two sum elements
  _mm256_store_pd(c, sum); // Store two sum elements

  // Increment pointers by 4 since AVX256 vectorizes on 256 bits = 32 bytes = 4*sizeof(double)
  a += 4;
  b += 4;
  c += 4;
 }

}
#endif

For SSE vectorization, I expect a Speedup equal around 2 because I align data on 128bits = 16 bytes = 2* sizeof(double).

我在 SSE 向量化结果中得到的结果如下图所示:

Results with SSE

因此,我认为这些结果是有效的,因为 SpeedUp 大约是因子 2。

现在对于 AVX256,我得到下图:

Results with AVX256

For AVX256 vectorization, I expect a Speedup equal around 4 because I align data on 256bits = 32 bytes = 4* sizeof(double).

但如您所见,我仍然得到一个因子 2 而不是 4 的 SpeedUp。

我不明白为什么我使用 SSE 和 AVX 获得相同的加速结果 矢量化。

它是否来自“编译标志”,来 self 的处理器模型,......我不知道。

以下是我为上述所有结果所做的编译命令行:

对于 SSE :

gcc-mp-4.9 -DSSE -O3 -msse main_benchmark.c -o vectorizedExe

对于 AVX256:

gcc-mp-4.9 -DAVX256 -O3 -Wa,-q -mavx main_benchmark.c -o vectorizedExe

此外,对于我的处理器型号,我可以使用 AVX512 矢量化吗? (一旦这个问题的问题就解决了)。

谢谢你的帮助

更新 1

我尝试了 @Mischa 的不同选项,但仍然无法通过 AVX 标志和选项获得 4 倍的加速。您可以在 http://example.com/test_vectorization/main_benchmark.c.txt 上查看我的 C 源代码(带有 .txt 扩展名以便直接查看浏览器)和用于基准测试的 shell 脚本是 http://example.com/test_vectorization/run_benchmark .

正如@Mischa 所说,我尝试应用以下命令行进行编译:

$GCC -O3 -Wa,-q -mavx -fprefetch-loop-arrays main_benchmark.c -o vectorizedExe

但生成的代码没有 AVX 指令。

如果您能看看这些文件,那就太好了。谢谢。

最佳答案

您正在为缓存->ram 传输撞墙。你的 core7 有一个 64 字节的缓存行。对于 sse2,16 字节存储需要 64 字节加载、更新和排队返回到 ram。 16 字节升序加载受益于自动预取预测,因此您获得了一些加载优势。添加目标内存的mm_prefetch;比方说,比下一个存储早 256 个字节。这同样适用于 avx2 32 字节存储。

关于c - 矢量化 - SSE、AVX 和 AVX2 的预期加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43245787/

相关文章:

c - 当 p 指向一个字符时,strcmp(p, "\n") 是未定义的行为吗?

python - Pandas 中的矢量化操作

c - union __m256 和两个 __m128 数组

c++ - 上证所该向上舍入时向下舍入

c - 为什么我在左移后得到 -256?

c - openSSL:如何初始化公钥加密的 key ?

indexing - Julia - 如何用索引向量的向量来索引向量?

numpy - 向量化梯度下降 Numpy

c++ - 高效的 SSE NxN 矩阵乘法

c++ - 如何使 res_query 与 dns 缓存一起工作?