簡體   English   中英

矢量化 - 加速SSE,AVX和AVX2的預期

[英]Vectorization - Speed up expected for SSE, AVX and AVX2

我正在使用以下處理器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

對於SSE矢量化,我期望加速等於2左右,因為我在128位= 16字節= 2 * sizeof(雙精度)上對齊數據。

我在SSE矢量化的結果中得到的結果如下圖所示:

結果與SSE

所以,我認為這些結果是有效的,因為SpeedUp是因子2。

現在對於AVX256,我得到下圖:

AVX256的結果

對於AVX256矢量化,我希望Speedup等於4,因為我在256bits = 32字節= 4 * sizeof(double)上對齊數據。

但正如你所看到的,我仍然得到一個factor 2而不是4的SpeedUp。

我不明白為什么我用SSE和AVX矢量化獲得相同的Speedup結果。

它來自我的處理器模型的“編譯標志”......我不知道。

以下是我為上述所有結果所做的編譯命令行:

對於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字節存儲。

NP。 有選擇:

(1)x86特定代碼:

#include <emmintrin.h> ... for (int i=size; ...) { _mm_prefetch(256+(char*)c, _MM_HINT_T0); ... _mm256_store_pd(c, sum);

(2)gcc特定代碼: for (int i=size; ...) { __builtin_prefetch(c+32); ... for (int i=size; ...) { __builtin_prefetch(c+32); ...

(3) gcc -fprefetch-array-loops ---編譯器最了解。

(3)如果你的gcc版本支持它是最好的。 如果你在相同的硬件上編譯和運行,那么(2)是次佳的。 (1)可移植到其他編譯器。

不幸的是,“256”是一種猜測,並且依賴於硬件。 128是最小值,512最大值,具體取決於您的CPU:RAM速度。 如果切換到_mm512*()_mm512*()這些數字加倍。

如果您正在處理各種處理器,我可以建議以涵蓋所有情況的方式進行編譯,然后測試cpuid(ax = 0)> = 7,然后cpuid(ax = 7,cx = 0):bx&0x04000010 at運行時(AVX2為0x10,AVX512為包含預取的為0x04000000)。

順便說一句,如果您使用gcc並指定-mavx或-msse2,編譯器會為您定義內置宏__AVX__或__SSE2__; 不需要-DAVX256。 為了支持過時的32位處理器,-m32遺憾地禁用了__SS​​E2__,因此有效地禁用了\\#include <emmintrin.h> :-P

HTH

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM