처음 SSE 내장 함수로 작업하고 있으며 16 바이트 메모리 정렬을 보장 한 후에도 세그먼트 화 오류가 발생합니다. 나는이 작업을 수행 할 때잘못된 메모리 정렬로 인해 SSE 내장 함수로 작업하는 동안 세그먼트 오류가 발생했습니다.
float *V = (float*) memalign(16,dx*sizeof(float));
:
How to allocate 16byte memory aligned data
이 내 배열을 선언하는 방법이다 :이 게시물을 내 이전 질문에 대한 확장
__m128 v_i = _mm_load_ps(&V[i]); //It works
그러나 내가 이렇게하면 :
__m128 u1 = _mm_load_ps(&V[(i-1)]); //There is a segmentation fault
,
하지만 내가 할 경우 :
__m128 u1 = _mm_loadu_ps(&V[(i-1)]); //It works again
그러나 나는 _mm_loadu_ps
를 사용하여 제거하고 단지 _mm_load_ps
를 사용하여 작동하도록 할 싶습니다.
저는 Intel icc 컴파일러를 사용하고 있습니다.
어떻게이 문제를 해결할 수 있습니까?
UPDATE :
다음 코드에서 두 작업을 사용하여 :
void FDTD_base (float *V, float *U, int dx, float c0, float c1, float c2, float c3, float c4)
{
int i, j, k;
for (i = 4; i < dx-4; i++)
{
U[i] = (c0 * (V[i]) //center
+ c1 * (V[(i-1)] + V[(i+1)])
+ c2 * (V[(i-2)] + V[(i+2)])
+ c3 * (V[(i-3)] + V[(i+3)])
+ c4 * (V[(i-4)] + V[(i+4)]));
}
}
SSE 버전 :
for (i=4; i < dx-4; i+=4)
{
v_i = _mm_load_ps(&V[i]);
__m128 center = _mm_mul_ps(v_i,c0_i);
__m128 u1 = _mm_loadu_ps(&V[(i-1)]);
u2 = _mm_loadu_ps(&V[(i+1)]);
u3 = _mm_loadu_ps(&V[(i-2)]);
u4 = _mm_loadu_ps(&V[(i+2)]);
u5 = _mm_loadu_ps(&V[(i-3)]);
u6 = _mm_loadu_ps(&V[(i+3)]);
u7 = _mm_load_ps(&V[(i-4)]);
u8 = _mm_load_ps(&V[(i+4)]);
__m128 tmp1 = _mm_add_ps(u1,u2);
__m128 tmp2 = _mm_add_ps(u3,u4);
__m128 tmp3 = _mm_add_ps(u5,u6);
__m128 tmp4 = _mm_add_ps(u7,u8);
__m128 tmp5 = _mm_mul_ps(tmp1,c1_i);
__m128 tmp6 = _mm_mul_ps(tmp2,c2_i);
__m128 tmp7 = _mm_mul_ps(tmp3,c3_i);
__m128 tmp8 = _mm_mul_ps(tmp4,c4_i);
__m128 tmp9 = _mm_add_ps(tmp5,tmp6);
__m128 tmp10 = _mm_add_ps(tmp7,tmp8);
__m128 tmp11 = _mm_add_ps(tmp9,tmp10);
__m128 tmp12 = _mm_add_ps(center,tmp11);
_mm_store_ps(&U[i], tmp12);
}
만 _mm_load_ps()
를 사용하여이 일을보다 효율적인 방법이 있나요를?
아키텍처에서 'sizeof (float)'란 무엇입니까? – ecatmur
@ecatmur : 저는 64 비트 컴퓨터에서 일하고 있습니다. 질문에 대답하지 않는 – PGOnTheGo
; 다양한 64 비트 ABI가 있습니다. – ecatmur