Click here to Skip to main content
15,881,709 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I would like to know if someone can think about a better solution for doing this stuff.

I have an array of byte raw bitmap data in 32bit format (RGBA)

I need to transform this array in an 24bit format by eliminating the alpha component.

Additionally i need to transpose the data by aligning the red component in the first part of the result array, the green in after the first 1/3 and the blue after the 2/3 because i'm doing an RLE compression after.

So instead of having an array that look like R,G,B,R,G,B,R.... i will have an array that look like R,R,R,R....G,G,G,G.....B,B,B,B

By doing this alignment, i have a better RLE compression because there is more chance to have alignment in each component between pixels.

I'm using unsafe and fixed pointer to do that. I'm getting something like 10ms (~31000 ticks) to process for a 8.3M byte array length. It seems to be low but i m doing a realtime screengrabbing and every ms is counting...


C#
byte[] d1 = new Byte[width*height*4];
// -- fill d1 with data
.....
// 
byte[] datain24format = new byte[width*heigth * 3];
unsafe
{
   fixed(byte* pd1=d1)
   {
      fixed(byte* pd24b=datain24format)
      {
         int* actualpointeur = (int*)pd1 + (datalenght / 4) - 1;

         byte* redindexp = (pd24b + (datain24format.Length / 3)) - 1;
         byte* greenindexp = (pd24b + (datain24format.Length / 3) * 2) - 1;
         byte* blueindexp = (pd24b + datain24format.Length) - 1;
         for (int i = datalenght - 1; i >= 0; i -= 4, actualpointeur--, redindexp--, greenindexp--, blueindexp--)
         {
               *redindexp = (byte)*(actualpointeur);
               *greenindexp = (byte)(*(actualpointeur) >> 8);
               *blueindexp = (byte)(*(actualpointeur) >> 16);
         }
    }
  }
}  




Update

i tried the loop unrolling (didn t know this tips before) by 16 operation (more doesn't make better performance)

My result is now 5ms (~15000 ticks) :)

here is my new loop :

C#
for (int i = _DataLenght - 1; i >= 0; i -= 64,  actualpointeur-=16,redindexp-=16,greenindexp-=16,blueindexp-=16)
{
                                            
 *redindexp = (byte)*(actualpointeur);
 *greenindexp = (byte)(*(actualpointeur) >> 8);
 *blueindexp = (byte)(*(actualpointeur) >> 16);
 *(redindexp-1) = (byte)*(actualpointeur-1);
 *(greenindexp-1) = (byte)(*(actualpointeur-1) >> 8);
 *(blueindexp-1) = (byte)(*(actualpointeur-1) >> 16);
......
 *(redindexp - 15) = (byte)*(actualpointeur - 15);
 *(greenindexp - 15) = (byte)(*(actualpointeur - 15) >> 8);
 *(blueindexp - 15) = (byte)(*(actualpointeur - 15) >> 16);
                                           
}
Posted
Updated 4-Feb-16 3:13am
v3

1 solution

Looks fairly to the point to me. Traditionally, I would try to stay away from byte sized pointers and use something more native (32 or 64) bit and use bit manipulation, to minimize the memory accesses. That said, I don't think it makes much difference on modern day CPUs.

Make sure you are using a release build! This will make a big difference.

I've done similar stuff when working with audio. One thing you could do which helps, but won't make a big difference is do more on each pass of the loop. Do ten pixels per loop iteration, then do anything left over in a second loop. This helps by increases the work done to branch ratio.

Always use local variables rather than member ones. This makes a huge difference, but you are already doing this.

Make sure you have set the thread/process priority to something mentally high, but be careful as you can kill the machine doing this.

The only other thing I can think of is going multithread, if you are on a multiple core machine. Could help, keep thread affinity on separate processors and split the work up. That said, because of the goings on with the various CPU caches, it might not make any difference.

Last thought - buy a super computer.
 
Share this answer
 
Comments
roks nicolas 4-Feb-16 8:17am    
tx rob for your suggestion.

I will try the loop unrolling.

I started another approch by using Gpu but for the moment, not so much improving...
Afzaal Ahmad Zeeshan 4-Feb-16 9:06am    
5ed.
roks nicolas 4-Feb-16 9:58am    
??

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