Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all.

I have a question on SSE operations.

I have 'm128i_i8 of __m128i' data that have as following.
C++
__m128i Mydata;
Mydata.m128i_i8[0] : 90
Mydata.m128i_i8[1] : 0
Mydata.m128i_i8[2] : 1
Mydata.m128i_i8[3] : 0
Mydata.m128i_i8[4] : 114
Mydata.m128i_i8[5] : 1
Mydata.m128i_i8[6] : 34
Mydata.m128i_i8[7] : 1
Mydata.m128i_i8[8] : 85
Mydata.m128i_i8[9] : 2
Mydata.m128i_i8[10] : 68
Mydata.m128i_i8[11] : 2
Mydata.m128i_i8[12] : 103
Mydata.m128i_i8[13] : 2
Mydata.m128i_i8[14] : 119
Mydata.m128i_i8[15] : 1


※ Question 1.
Can I convert data following as ?
C++
__m128i result;
result.m128i_i8[0] : 90
result.m128i_i8[1] : 1
result.m128i_i8[2] : 114
result.m128i_i8[3] : 34
result.m128i_i8[4] : 85
result.m128i_i8[5] : 68
result.m128i_i8[6] : 103
result.m128i_i8[7] : 119
result.m128i_i8[8] : 0
result.m128i_i8[9] : 0
result.m128i_i8[10] : 0
result.m128i_i8[11] : 0
result.m128i_i8[12] : 0
result.m128i_i8[13] : 0
result.m128i_i8[14] : 0
result.m128i_i8[15] : 0


※ Question 2.
If I have as following data.
C++
Mydata.m128i_i16[0] : 90
Mydata.m128i_i16[1] : 1
Mydata.m128i_i16[2] : 114
Mydata.m128i_i16[3] : 222
Mydata.m128i_i16[4] : 341
Mydata.m128i_i16[5] : 444
Mydata.m128i_i16[6] : 359
Mydata.m128i_i16[7] : 119


Can I convert as following?
(Threshold is 255)

C++
__m128i result;
result.m128i_i8[0] : 90
result.m128i_i8[1] : 1
result.m128i_i8[2] : 114
result.m128i_i8[3] : 222
result.m128i_i8[4] : 255
result.m128i_i8[5] : 255
result.m128i_i8[6] : 255
result.m128i_i8[7] : 119
result.m128i_i8[8] : 0
result.m128i_i8[9] : 0
result.m128i_i8[10] : 0
result.m128i_i8[11] : 0
result.m128i_i8[12] : 0
result.m128i_i8[13] : 0
result.m128i_i8[14] : 0
result.m128i_i8[15] : 0


My code:
C++
__m128i result = _mm_setzero_si128();
result = _mm_packs_epi16(Mydata,_mm_setzero_si128());


Please advise me. Thank you. :)

What I have tried:

I tried to use '_mm_packs_epi16' operation but result is strange.
Posted
Updated 11-Apr-16 13:58pm
v6
Comments
nv3 11-Apr-16 6:47am    
You have to show your code for someone being able to help you. Yes, _mm_packs_epi16 does pack your 16-bit integers into 8-bit integers, but with saturation. That means that for example a value of 346 (represented as bytes 90 1) is converted to 127, which is the highest signed 8-bit integer. Is that what you mean by "result is strange"?
kgg124 11-Apr-16 7:57am    
Thank you for your reply.
I have same result. If value is larger than 127, it converted to 127.

1 solution

To my knowledge there is no SSE instruction that does the packing without saturation. But I am admittedly no expert at SSE2.

See here for the SSE2 reference on the Microsoft website:

Integer Intrinsics Using Streaming SIMD Extensions 2[^]

Of course you can use conventional instruction to accomplish what you want. Just treat the memory representation of your 128-bit item as byte array and do the packing in a little loop. That's just two lines of code and if you don't do that extensively it will be not that much slower than an SSE2 instruction.
 
Share this answer
 
v2
Comments
kgg124 11-Apr-16 20:06pm    
Thank you for your reply.
I tried to as following on my Question2.

for(int k=0;k<8; k++)
{
result.m128i_i8[k] = sum_tot.m128i_i16[k];
}

It works well. But so slow..
Is other good way?
nv3 12-Apr-16 2:52am    
Not to my knowledge. But perhaps one of the SSE2 gurus can comment on this.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900