This is the first time I've been working with SSE's built-in features, and I ran into the problem of segmentation even after ensuring memory alignment of 16 bytes. This post is a continuation of my previous question:
How to allocate 16-byte data with memory alignment
This is how I declared my array:
float *V = (float*) memalign(16,dx*sizeof(float));
When I try to do this:
__m128 v_i = _mm_load_ps(&V[i]);
But when I do this:
__m128 u1 = _mm_load_ps(&V[(i-1)]);
But if I do this:
__m128 u1 = _mm_loadu_ps(&V[(i-1)]);
However, I want to exclude the use of _mm_loadu_ps
and want it to work only with _mm_load_ps
.
I am working with Intel icc compiler.
How to solve this problem?
UPDATE:
using both operations in the following code:
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])
SSE Version:
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); }
Is there a more efficient way to do this using only _mm_load_ps()
?