使用SSE进行矢量化的结果错误

时间:2014-01-28 22:13:09

标签: c x86 vectorization sse simd

以下代码生成以下输出:

6 6 0 140021597270387

表示只正确计算前两个位置。但是,我正在处理longs(4个字节)而__m128i可以容纳超过4个long。

long* AA = (long*)malloc(32*sizeof(long));
long* BB = (long*)malloc(32*sizeof(long));

for(i = 0; i<4;i++){
    AA[i] = 2;
    BB[i] = 3;
}

__m128i* m1 = (__m128i*) AA;
__m128i* m2 = (__m128i*) BB;

__m128i m3 = _mm_mul_epu32(m1[0],m2[0]);

long* CC = (long*) malloc(16 * sizeof(long));
CC = (long*)&m3;

for (i = 0; i < 4; i++)
    printf("%ld \n",CC[i]);

分配:

long* AA = (long*) memalign(16 * sizeof(long), 16);

(和其余的矢量)生成一个seg。故障。有人可以评论吗?

由于

1 个答案:

答案 0 :(得分:4)

1)不要使用像long这样的不确定大小的类型,使用特定的固定类型,例如uint32_t

2)不要使用malloc - 不能保证返回16字节对齐的内存,使用memalign或等效的*

3)不要将malloc(或任何其他函数返回void *)的结果转换为C

4)不需要再分配另一个缓冲区来打印结果

固定代码:

uint32_t* AA = memalign(32*sizeof(uint32_t), 16);
uint32_t* BB = memalign(32*sizeof(uint32_t), 16);

for (i = 0; i < 4; i++){
    AA[i] = 2;
    BB[i] = 3;
}

__m128i* m1 = (__m128i*)AA;
__m128i* m2 = (__m128i*)BB;

__m128i m3 = _mm_mul_epu32(m1[0], m2[0]);    // 2 x 32x32->64 bit unsigned multiplies -> m3

uint64_t* CC = (uint64_t*)&m3;

for (i = 0; i < 2; i++)                      // display 2 x 64 bit result values
    printf("%llu\n", CC[i]);

*请注意,根据您的平台,您可能需要使用memalign以外的呼叫才能分配适当对齐的内存,例如posix_memalign_mm_malloc_aligned_malloc(WIN32)。