簡體   English   中英

矢量化失敗了GCC

[英]vectorization fails with GCC

我試圖理解矢量化,但令我驚訝的是這個非常簡單的代碼沒有被矢量化

#define n 1024
int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];
}

雖然英特爾編譯器由於某種原因導致初始化循環,第5行。

> icc -vec-report a.c
a.c(5): (col. 3) remark: LOOP WAS VECTORIZED

有了海灣合作委員會,我似乎一無所獲

> gcc -ftree-vectorize -ftree-vectorizer-verbose=2 a.c

難道我做錯了什么? 這不應該是一個非常簡單的可矢量化循環嗎? 所有相同的操作,連續存儲器等。我的CPU支持SSE1 / 2/3/4。

--- 更新 ---

根據下面的答案,這個例子對我有用。

#include <stdio.h>
#define n 1024

int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];

  printf("%d\n", c[1023]);  
}

用icc

> icc -vec-report a.c
a.c(7): (col. 3) remark: LOOP WAS VECTORIZED
a.c(8): (col. 3) remark: LOOP WAS VECTORIZED

和gcc

> gcc -ftree-vectorize -fopt-info-vec -O a.c
a.c:8:3: note: loop vectorized
a.c:7:3: note: loop vectorized

我稍微修改了你的源代碼,以確保GCC無法刪除循環:

#include <stdio.h>
#define n 1024

int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];

  printf("%d\n", c[1023]);  
}

GCC(v4.8.2)可以對兩個循環進行向量化,但它需要-O標志:

gcc -ftree-vectorize -ftree-vectorizer-verbose=1 -O2 a.c

我得到:

在ac:8處分析循環

在ac:8處矢量化循環

ac:8注意:LOOP VECTORIZED。 在ac:7處分析循環

在ac:7處矢量化循環

ac:7注意:LOOP VECTORIZED。 ac:注意:函數中的矢量化2個循環。

使用-fdump-tree-vect開關GCC會將更多信息轉儲到ac##t.vect文件中(了解“內部”發生的事情非常有用)。

還要考慮:

大多數情況下,選項-Ofast -march=native會將代碼矢量化,如果它可以在您的處理器上。

$ gcc compute_simple.c -Ofast -march=native -fopt-info-vec -o compute_simple.bin
compute_simple.c:14:5: note: loop vectorized
compute_simple.c:14:5: note: loop versioned for vectorization because of possible aliasing
compute_simple.c:14:5: note: loop vectorized

要知道您的處理器是否可以執行此操作,請使用lscpu並查看可用的標志。

$ lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              12
...
Vendor ID:           GenuineIntel
...
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge  
 mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall   
nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl   
xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64   
monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1   
sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand   
lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb   
stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1   
hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt   
xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify   
hwp_act_window hwp_epp md_clear flush_l1d

你需要英特爾的sse / avx,ARM的霓虹燈,AMD的其他產品(如xop)。

您可以通過搜索gcc文檔找到有關矢量化的更多信息。

這是一篇關於這個主題的好文章,其中包含可用於許多平台的標志: https//gcc.gnu.org/projects/tree-ssa/vectorization.html

最后,如上所述,在舊版本的gcc中使用-ftree-vectorizer-verbose=n ,在最近的版本中使用-fopt-info-vec來查看矢量化的內容。

暫無
暫無

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

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