루프는 outArray[z]
에 쓸 때 루프 종속성이 있습니다. CPU가 한 번에 두 개 이상의 부동 소수점 합을 처리 할 수 있지만 현재 루프에서는 outArray[z]
의 합계 만 허용됩니다. 이 문제를 해결하려면 루프를 해제해야합니다. SIMD의 측면에서
for (int z=0; z<temp; z+=2) {
float findex_v1 = a + b * A[z];
int iindex_v1 = findex_v1;
outArray[z] += inArray[iindex_v1] + (findex_v1 - iindex_v1) * (inArray[iindex_v1+1] - inArray[iindex_v1]);
float findex_v2 = (a+1) + b * A[z+1];
int iindex_v2 = findex_v2;
outArray[z+1] += inArray[iindex_v2] + (findex_v2 - iindex_v2) * (inArray[iindex_v2+1] - inArray[iindex_v2]);
a+=2;
}
문제는 당신이 inArray[iindex_v1]
에 액세스 할 때 비 연속 데이터를 수집해야한다는 것입니다. AVX2에는 수집 지침이 있지만 사용하지 않았습니다. 그렇지 않으면 SIMD없이 모임을하는 것이 가장 좋습니다. z
에 액세스하는 모든 작업은 인접한 메모리에 액세스하므로 쉽게 작업 할 수 있습니다. 푸시 코드 (언 롤링하지 않음)는 다음과 같이 표시됩니다.
int indexa[4];
float inArraya[4];
float dinArraya[4];
int4 a4 = a + float4(0,1,2,3);
for (int z=0; z<temp; z+=4) {
//use SSE for contiguous memory
float4 findex4 = a4 + b * float4.load(&A[z]);
int4 iindex4 = truncate_to_int(findex4);
//don't use SSE for non-contiguous memory
iindex4.store(indexa);
for(int i=0; i<4; i++) {
inArraya[i] = inArray[indexa[i]];
dinArraya[i] = inArray[indexa[i+1]] - inArray[indexa[i]];
}
//loading from and array right after writing to it causes a CPU stall
float4 inArraya4 = float4.load(inArraya);
float4 dinArraya4 = float4.load(dinArraya);
//back to SSE
float4 outArray4 = float4.load(&outarray[z]);
outArray4 += inArray4 + (findex4 - iindex4)*dinArray4;
outArray4.store(&outArray[z]);
a4+=4;
}
무엇이 수행되는지 알려주십시오. A가 무엇입니까? 어셈블리 출력에서 확인 했습니까? – Marco
'z ++'을'++ z'로 바꾸는 것은 좋은 생각입니다. – user2485710
@ user2485710 : 왜 다른 점이 있습니까? –