정렬,로드 및 저장 만 사용하여 2D 스텐실을 벡터화하려고합니다. 이를 위해 본질적으로 _mm_load_ps
및 _mm_shuffle_ps
을 사용하여 원하는 주소를 얻으려고합니다.SSE 내장 함수를 사용하여 2D 스텐실 벡터화
코드의 내 스칼라 버전은 다음과 같습니다
void FDTD_base (float *V, float *U, int dx, int dy, float c0, float c1, float c2, float c3, float c4)
{
int i, j, k;
for (j = 4; j < dy-4; j++)
{
for (i = 4; i < dx-4; i++)
{
U[j*dx+i] = (c0 * (V[j*dx+i]) //center
+ c1 * (V[j*dx+(i-1)] + V[(j-1)*dx+i] + V[j*dx+(i+1)] + V[(j+1)*dx+i])
+ c2 * (V[j*dx+(i-2)] + V[(j-2)*dx+i] + V[j*dx+(i+2)] + V[(j+2)*dx+i])
+ c3 * (V[j*dx+(i-3)] + V[(j-3)*dx+i] + V[j*dx+(i+3)] + V[(j+3)*dx+i])
+ c4 * (V[j*dx+(i-4)] + V[(j-4)*dx+i] + V[j*dx+(i+4)] + V[(j+4)*dx+i]));
}
}
}
내 벡터 지금까지 코드의 버전을 참조하십시오
이 for (j = 4; j < dy-4; j++)
{
for (i = 4; i < dx-4; i+=4)
{
__m128 b = _mm_load_ps(&V[j*dx+i]);
center = _mm_mul_ps(b,c0_i);
a = _mm_load_ps(&V[j*dx+(i-4)]);
c = _mm_load_ps(&V[j*dx+(i+4)]);
d = _mm_load_ps(&V[(j-4)*dx+i]);
e = _mm_load_ps(&V[(j+4)*dx+i]);
u_i2 = _mm_shuffle_ps(a,b,_MM_SHUFFLE(1,0,3,2));//i-2
u_i6 = _mm_shuffle_ps(b,c,_MM_SHUFFLE(1,0,3,2));//i+2
u_i1 = _mm_shuffle_ps(u_i2,b,_MM_SHUFFLE(2,1,2,1));//i-1
u_i5 = _mm_shuffle_ps(b,u_i6,_MM_SHUFFLE(2,1,2,1));//i+1
u_i3 = _mm_shuffle_ps(a,u_i2,_MM_SHUFFLE(2,1,2,1));//i-3
u_i7 = _mm_shuffle_ps(u_i6,c,_MM_SHUFFLE(2,1,2,1));//i+3
u_i4 = a; //i-4
u_i8 = c; //i+4
누군가가 J-1의 위치를 얻기에 좀 도와 줄래, J + 1 ..... j-4, j + 4이다.
이 작동하지 않습니다
u_j2 = _mm_shuffle_ps(d,b,_MM_SHUFFLE(1,0,3,2));//j-2 (this is incorrect)
u_j6 = _mm_shuffle_ps(b,e,_MM_SHUFFLE(1,0,3,2));//j+2
u_j1 = _mm_shuffle_ps(u_j2,b,_MM_SHUFFLE(2,1,2,1));//j-1
u_j5 = _mm_shuffle_ps(b,u_j6,_MM_SHUFFLE(2,1,2,1));//j+1
u_j3 = _mm_shuffle_ps(d,u_j2,_MM_SHUFFLE(2,1,2,1));//j-3
u_j7 = _mm_shuffle_ps(u_j6,e,_MM_SHUFFLE(2,1,2,1));//j+3
u_j4 = d; //j-4 (this is fine)
u_j8 = e; //j+4
나는 정렬되지 않은로드를 사용하지 않고 (j-1)*dx+i
, (j+1)*dx+1
..... (j-4)*dx+i
및 (j+4)*dx+i
을 얻는 방법을 결정하는 데에만 도움이 필요합니다.
가능성있는 해결책으로 에 저장된 주소에 변위 3*dx
을 추가하여 (j-1)*dx+i
을 얻는 것을 생각했습니다. 그리고, 에 저장된 주소에 3*dx
의 변위를 빼서 (j+1)*dx+i
을 얻습니다. 마찬가지로 주소가 d
인 경우 2*dx
을 추가하여 j-2
등을 얻습니다. 하지만 SSE 내장 함수를 사용하여이 전략을 구현하는 방법을 알지 못합니다.
도와주세요. Intel icc 컴파일러를 사용하고 있습니다.
중복 가능성 http://stackoverflow.com/questions/11085924/segmentation-fault-while-working-with-sse-intrinsics-due-to ([분할 오류가 잘못되어 메모리 배열에 SSE 내장 함수 작업하는 동안] -incorrect-memory-ali) –
@Paul : 정확하지 않습니다. stride 값이있을 때'mm_shuffle_ps'를 사용하는 방법을 결정하려고합니다.이전 게시물은 1D 슬라이딩 윈도우 용이었습니다. 이것은 2D 슬라이딩 윈도우입니다.이 슬라이딩 윈도우는 새로운 차원으로 복잡해졌습니다. 어떤 도움이라도 매우 도움이 될 것입니다. – PGOnTheGo
귀하의 모든 제약 조건은 확실합니까? 예 : 절대 정렬되지 않은로드 및 상점이 없습니까? Nehalem 이후의 Intel CPU에서 특히 효율적으로 동일한 계산을 표현하는 다른 방법이 있지만 정렬되지 않은로드 및 저장이 필요합니다. –