作者fielia (フィーリア)
看板Programming
标题Re: [问题] 有关sse取值的问题
时间Fri Nov 12 12:20:51 2010
※ 引述《wang71 (jack)》之铭言:
: 各位大大,小弟目前在研究有关sse的加速
: 目前想写一个两个rgb像素(rgb为unsigned char)
: 相减,取绝对值,在将最後的rgb相加
: 然後目前有使用到这个函数
: __m128i _mm_sad_epu8(__m128i a, __m128i b)
: 只是目前有个问题是例如:
: c = _mm_sad_epu8( a, b)
: 但是要如何把c的值取出呢?
: 一直没看到相关的指令
: 希望各位大大帮忙~~~~
SSE有bit shifting的_mm_slli_si128()和_mm_srli_si128()的函数
PSLLDQ PSRLDQ <---组合语言
可以把你要的byte shift到最右边,再挖出来
不过这样取值很慢就是
要想得到SSE高效能的好处
正确的做法是
1.用union
union内有__m128i时,用此union宣告的变数就会align 16byte
void test1(){
typedef union{
__m128i v;
unsigned char c[16];
}your_pixel4_type;
your_pixel4_type z;
your_pixel4_type y;
your_pixel4_type x;
for(int i=0;i<16;++i){
z.c[i]=i;
y.c[i]=i;
}
__m128i a=_mm_load_si128(&z.v);
__m128i b=_mm_load_si128(&y.v);
__m128i c=_mm_srli_si128(a,1);
_mm_store_si128(&x.v,c);
for(int i=0;i<16;++i)
printf("%d\n",x.c[i]);
}
2. 用pointer,不过要注意,不能用libc内建的malloc()
void test2(){
const int ALIGN=16;
int *a,*b,*c;
int a_length=128;
a=(int*)_mm_malloc(sizeof(int)*a_length,ALIGN);
b=(int*)_mm_malloc(sizeof(int)*a_length,ALIGN);
c=(int*)_mm_malloc(sizeof(int)*a_length,ALIGN);
for(int i=0;i<a_length;++i){
a[i]=i;
b[i]=i;
}
// 普通pointer转型成__m128i pointer
__m128i* ma=(__m128i*)a;
__m128i* mb=(__m128i*)b;
__m128i* mc=(__m128i*)c;
// 找到ma的结尾
int ma_length = a_length*sizeof(int)/ALIGN;
__m128i* ma_end;
ma_end = ma+ma_length;
//ma,mb,mc都必须是pointer
for(;ma<ma_end;++ma,++mb,++mc){
__m128i xmm0=_mm_load_si128(ma);
__m128i xmm1=_mm_load_si128(mb);
__m128i xmm2=_mm_add_epi32(xmm0,xmm1);
_mm_store_si128(mc,xmm2);
}
for(int i=0;i<a_length;++i){
printf("%d\n",c[i]);
}
_mm_free(a);
_mm_free(b);
_mm_free(c);
}
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.54
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.54
1F:推 wang71:大大太强了,请界我转贴小弟的部落格好吗 ^^ 140.96.76.143 12/02 11:23