我有一个包含 0 或 1 的 16 字符 vector ,我想使用 SSE 添加每 4 个非重叠元素。
没有矢量化的代码的简化版本如下所示
char a[16]={1,0,0,1 ,0,0,1,0, 0,1,0,0, 0,0,0,1};
char sum1 = a[0] + a[1] + a[2] + a[3];
char sum2 = a[4] + a[5] + a[6] + a[7];
char sum3 = a[8] + a[9] + a[10] + a[11];
char sum4 = a[12] + a[13] + a[14] + a[15];
在我的应用程序中, vector 的长度远大于 16,但它始终是 16 的倍数。我使用其他 SSE 逻辑运算获得此 vector ,这些运算为我提供了良好的加速,所以我想知道我如何可以向量化这些添加。下面是完整的代码,其中 vec1、vec2 和 vec3 具有相同的长度 n(16 的倍数)并且 vector 计数为 n/4。
void myfunc( const char *vec1, const char *vec2, char *vec3, int *counts, int n){
__m128i *r1 = (__m128i*)vec1;
__m128i *r2 = (__m128i*)vec2;
char *a = vec3;
char temp[16] __attribute__ ((aligned (16)));
for ( int i = 0; i < n; i+=16, r1++, r2++, a+=16 ) {
_mm_store_si128((__m128i*)a, _mm_and_si128(*r1, *r2));
_mm_store_si128((__m128i*)temp, _mm_or_si128(*r1, *r2));
char size = a[0]+a[1]+a[2]+a[3];
if( size == 0 ){
memcpy(a, temp, 4*sizeof(char));
counts[k]++;
}
k++;
size = a[4]+a[5]+a[6]+a[7];
if( size == 0 ){
memcpy(a+4, temp+4, 4*sizeof(char));
counts[k]++;
}
k++;
size = a[8]+a[9]+a[10]+a[11];
if( size == 0 ){
memcpy(a+8, temp+8, 4*sizeof(char));
counts[k]++;
}
k++;
size = a[12]+a[13]+a[14]+a[15];
if( size == 0 ){
memcpy(a+12, temp+12, 4*sizeof(char));
counts[k]++;
}
k++;
}
}
如有任何帮助,我们将不胜感激。
最佳答案
您可以比较整数而不是比较字节。将 a
、temp
和 counts
中的四个整数加载到 SSE 寄存器中(称它们为 a4
、tmp4
,以及下面代码中的 counts4
)。然后你可以用 SSE 一次处理四个整数。这假设 counts 是一个 int32 数组。
例如,我们假设 a4 = {0,3,0,4},counts4 = {1,2,3,4},tmp4 = {5,6,7,8}。在下面的代码中
test
将为 {-1, 0, -1, 0}。从计数中减去计数得到计数 = {2,2,4,4}。 test
与 tmp4
的逻辑与是 {5,0,7,0}。将其添加到 a4 得到 a4 = {5,3,7,4}。这应该可以满足您的要求。
for ( int i = 0; i < n; i+=16, r1++, r2++, a+=16, k+=4 ) {
_mm_store_si128((__m128i*)a, _mm_and_si128(*r1, *r2));
_mm_store_si128((__m128i*)temp, _mm_or_si128(*r1, *r2));
__m128i a4 = _mm_load_si128((__m128i*)a);
__m128i tmp4 = _mm_load_si128((__m128i*)tmp);
__m128i counts4 = _mm_load_si128((__m128i*)&counts[k]);
__m128i test = _mm_cmpeq_epi32(_mm_set1_epi32(0), a4);
a4 = _mm_add_epi32(a4, _mm_and_si128(tmp4,test));
counts4 = _mm_sub_epi32(counts4, test);
_mm_store_si128((__m128i*)a, a4);
_mm_store_si128((__m128i*)counts, counts4);
}
关于c - SSE 添加字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23072866/