我有一個內環如本如何讓ICC編譯器在內部循環中生成SSE指令?
for(i=0 ;i<n;i++){
x[0] += A[i] * z[0];
x[1] += A[i] * z[1];
x[2] += A[i] * z[2];
x[3] += A[i] * z[3];
}
內4個指令可以由編譯器可以容易地轉化爲SSE指令。目前的編譯器是否這樣做?如果他們做了我必須做的事情來強制編譯器執行此操作?
我有一個內環如本如何讓ICC編譯器在內部循環中生成SSE指令?
for(i=0 ;i<n;i++){
x[0] += A[i] * z[0];
x[1] += A[i] * z[1];
x[2] += A[i] * z[2];
x[3] += A[i] * z[3];
}
內4個指令可以由編譯器可以容易地轉化爲SSE指令。目前的編譯器是否這樣做?如果他們做了我必須做的事情來強制編譯器執行此操作?
從您提供的內容來看,這不能被矢量化,因爲指針可能互相混淆,即x
陣列可能與A
或z
重疊。
幫助編譯器出來的一種簡單方法是聲明x
爲__restrict
。另一種方法是重寫它像這樣:
for(i=0 ;i<n;i++)
{
float Ai=A[i];
float z0=z[0], z1=z[1], z2=z[2], z3=z[3];
x[0] += Ai * z0;
x[1] += Ai * z1;
x[2] += Ai * z2;
x[3] += Ai * z3;
}
我從未試圖讓編譯器來自動向量化的代碼,所以我不知道這是否會做不做。即使它沒有被矢量化,它也應該更快,因爲可以更有效地訂購加載和存儲,而不會導致加載存儲。如果你有比編譯器更多的信息(例如你的指針是否是16字節對齊的),並且應該能夠使用它(例如使用對齊的加載)。請注意,我並不是說你應該總是試圖擊敗編譯器,只有當你知道比它更多的時候。
進一步閱讀:
ICC自動向量化下面的代碼片斷爲SSE2:
void foo(float *__restrict__ x, float *__restrict__ A, float *__restrict__ z, int n){
for(int i=0;i<n;i++){
x[0] += A[i] * z[0];
x[1] += A[i] * z[1];
x[2] += A[i] * z[2];
x[3] += A[i] * z[3];
}
return;
}
通過使用restrict關鍵字,內存別名假設被忽略。生成的量化報告:
$ icpc test.cc -c -vec-report2 -S
test.cc(2): (col. 1) remark: PERMUTED LOOP WAS VECTORIZED
test.cc(3): (col. 2) remark: loop was not vectorized: not inner loop
要確認如果產生了SSE指令,打開ASM生成(test.s),你會發現下面的說明:
..B1.13: # Preds ..B1.13 ..B1.12
movaps (%rsi,%r15,4), %xmm10 #3.10
movaps 16(%rsi,%r15,4), %xmm11 #3.10
mulps %xmm0, %xmm10 #3.17
mulps %xmm0, %xmm11 #3.17
addps %xmm10, %xmm9 #3.2
addps %xmm11, %xmm6 #3.2
movaps 32(%rsi,%r15,4), %xmm12 #3.10
movaps 48(%rsi,%r15,4), %xmm13 #3.10
movaps 64(%rsi,%r15,4), %xmm14 #3.10
movaps 80(%rsi,%r15,4), %xmm15 #3.10
movaps 96(%rsi,%r15,4), %xmm10 #3.10
movaps 112(%rsi,%r15,4), %xmm11 #3.10
addq $32, %r15 #2.1
mulps %xmm0, %xmm12 #3.17
cmpq %r13, %r15 #2.1
mulps %xmm0, %xmm13 #3.17
mulps %xmm0, %xmm14 #3.17
addps %xmm12, %xmm5 #3.2
mulps %xmm0, %xmm15 #3.17
addps %xmm13, %xmm4 #3.2
mulps %xmm0, %xmm10 #3.17
addps %xmm14, %xmm7 #3.2
mulps %xmm0, %xmm11 #3.17
addps %xmm15, %xmm3 #3.2
addps %xmm10, %xmm2 #3.2
addps %xmm11, %xmm1 #3.2
jb ..B1.13 # Prob 75% #2.1
# LOE rax rdx rsi r8 r9 r10 r13 r15 ecx ebp edi r11d r14d bl xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9
..B1.14: # Preds ..B1.13
addps %xmm6, %xmm9 #3.2
addps %xmm4, %xmm5 #3.2
addps %xmm3, %xmm7 #3.2
addps %xmm1, %xmm2 #3.2
addps %xmm5, %xmm9 #3.2
addps %xmm2, %xmm7 #3.2
lea 1(%r14), %r12d #2.1
cmpl %r12d, %ecx #2.1
addps %xmm7, %xmm9 #3.2
jb ..B1.25 # Prob 50% #2.1