f = (((((c & 0xFF0000) >> 16) * ((m & 0xFF0000) >> 16)) >> 8) << 16) | ((((c & 0x00FF00) * (m & 0x00FF00)) >> 24) << 8) | (((c & 0x0000FF) * (m & 0x0000FF)) >> 8);
Can you get it smaller and more efficient?
🔒 Locked
Parallel multiplication
Advertisement
Original Post
I have 2 32-bit integers c and m. Each 32-bit integer contains 3 bytes at positions 00FF0000, 0000FF00 and 000000FF (so the first byte of the 32-bit integer contains no data). I want to multiply each byte of c with the corresponding byte of m, and store that into the 32-bit integer f. I want to do this in one line of C++ code, and in the way with the fewest operations possible. I can't get it any smaller than this though:
Quote:
Original post by Trap
You use your int as a byte[4] vector and want a dot-product for the special case of byte[0]==0?
No it's not a vector it's an RGB color (with the alpha channel being ignored), and it's not the dot product but a component-wise product.
And it's for fun! (I came up with it while coding tho and might still use it ;))
When you're doing this kind of optimization you need to know the hardware. Can it shift fast? Fast multiplications or should you use tables? Memory bandwidth limited? If you miss the level1-3 caches the CPU may stall for hundreds of clock cycles and _this_ is the bottleneck - not processing the pixels/colors.
The _optimizations_ are often not portable - keep the original, clean code for the future!
You can do this with two multiplications instead of three :-P
Also, you don't need to shift all color components around this much. Draw each of the color components as bit-ranges on a piece of paper _separately_ and figure-out the optimal set of logical operations for each component.
Another thing you can think about: right now there are a lot of dependencies between the different operations that can cause CPU stalls. Try interleaving other stuff in between - possible interleave the same code but processing another color (pixel?) at the same time. Depending on HW, the second pixel might be "free" CPU-wize = 200% faster.
Yet another thing: if this code is the biggest bottleneck, can you preprocess your data to make this code snippet do less work?
HTH
/Marcus
The _optimizations_ are often not portable - keep the original, clean code for the future!
You can do this with two multiplications instead of three :-P
Also, you don't need to shift all color components around this much. Draw each of the color components as bit-ranges on a piece of paper _separately_ and figure-out the optimal set of logical operations for each component.
Another thing you can think about: right now there are a lot of dependencies between the different operations that can cause CPU stalls. Try interleaving other stuff in between - possible interleave the same code but processing another color (pixel?) at the same time. Depending on HW, the second pixel might be "free" CPU-wize = 200% faster.
Yet another thing: if this code is the biggest bottleneck, can you preprocess your data to make this code snippet do less work?
HTH
/Marcus
Quote:
Original post by Trap
Why don't you just load every part as an unsigned char, multiply them and store again? Maybe by using a union of 1 int and 4 unsigned chars.
That's not one line of code. I'm looking for something that looks "cool", not necessarily readable, like that way to swap two variables in one statement ;)
I profiled that single line variable swap once. It was something like 4 times slower. You ended up with the same number of mov instructions, it just did an XOR between everything.
Keep it simple.
//Using temporary int temp = two;00411A2C mov eax,dword ptr [two]00411A2F mov dword ptr [temp],eax two = one;00411A32 mov eax,dword ptr [one] 00411A35 mov dword ptr [two],eax one = temp;00411A38 mov eax,dword ptr [temp] 00411A3B mov dword ptr [one],eax //Using XOR one ^= two ^= one ^= two;00411A3E mov eax,dword ptr [one] 00411A41 xor eax,dword ptr [two] 00411A44 mov dword ptr [one],eax 00411A47 mov ecx,dword ptr [two] 00411A4A xor ecx,dword ptr [one] 00411A4D mov dword ptr [two],ecx 00411A50 mov edx,dword ptr [one] 00411A53 xor edx,dword ptr [two] 00411A56 mov dword ptr [one],edx Keep it simple.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement