Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to simulate integer bitwise operations for _m256 types on AVX?

Tags:

c++

c

integer

avx

sse

I have a boolean expression that I have managed to implement in SSE2. Now I would have liked to try implementing it in AVX exploiting an additional factor 2 in parallelism increase (from 128 bit SIMD type to 256). However, AVX does not support integer operation (which AVX2 does, but I am working on a Sandy Bridge processor so it is not an option currently). However, since there are AVX intrinsics for bitwise operations. I figured I could make a try by just converting my integer types to float types and see if it works.

First test was a success:

__m256 ones = _mm256_set_ps(1,1,1,1,1,1,1,1);
__m256 twos = _mm256_set_ps(2,2,2,2,2,2,2,2); 
__m256 result = _mm256_and_ps(ones, twos);

I'm guetting all 0's as I am supposed to. Simularly AND'ing the twos instead I get a result of 2. But when trying 11 XOR 4 accordingly:

__m256 elevens = _mm256_set_ps(11,11,11,11,11,11,11,11); 
__m256 fours = _mm256_set_ps(4,4,4,4,4,4,4,4); 
__m256 result2 = _mm256_xor_ps(elevens, fours); 

The result is 6.46e-46 (i.e. close to 0) and not 15. Simularly doing 11 OR 4 gives me a value of 22 and not 15 as it should be. I don't understand why this is. Is it a bug or some configuration I am missing?

I was actually expecting my hypothesis of working with float as if they were integers to not work since the integer initialized to a float value might not actually be the precise value but a close approximation. But even then, I am surprised by the result I get.

Does anyone have a solution to this problem or must I upgrade my CPU to get AVX2 support enable this?

like image 837
Toby999 Avatar asked Dec 11 '13 19:12

Toby999


People also ask

Which data types can be used with bitwise operators?

Bitwise operators work on binary digits or bits of input values. We can apply these to the integer types – long, int, short, char, and byte.

How do you perform bitwise operations?

The bitwise AND operator ( & ) compares each bit of the first operand to the corresponding bit of the second operand. If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0. Both operands to the bitwise AND operator must have integral types.

What are AVX intrinsics?

AVX provides intrinsic functions that combine one or more values into a 256-bit vector. Table 2 lists their names and provides a description of each. There are similar intrinsics that initialize 128-bit vectors, but those are provided by SSE, not AVX.

Which Bitwise operator is used to set any bit in a number?

Explanation: Bitwise operator | can be used to “set” a particular bit while bitwise operator & can be used to “reset” a particular bit.


1 Answers

The first test worked by accident.

1 as a float is 0x3f800000, 2 is 0x40000000. In general, it wouldn't work that way.

But you can absolutely do it, you just have to make sure that you're working with the right bit-pattern. Don't convert your integers to floats - reinterpret-cast them. That corresponds to intrinsics such as _mm256_castsi256_ps, or storing your ints to memory and reading them as floats (that won't change them, in general only math operations care about what the floats mean, the rest work with the raw bit patterns, check the list of exceptions that an instruction can make to make sure).

like image 88
harold Avatar answered Nov 15 '22 10:11

harold