9

In C, I can define a pointer to an array like this:

char b1[SOME_SIZE];
char (*b3)[3]=(char(*)[3])b1;

so that b3[i][j] == b1[i*3+j].

Can I declare such a pointer, b3, in unsafe C#?

My intention is to access bitmap channels as:

///...
unsafe {
    //...
    byte *target; //8bpp
    byte (*source)[3]; //24bpp
    //...
    target[x]=(source[x][0]+source[x][1]+source[x][2])/3;
    //...

I hope this way, using source[x][ch] instead of source[x*3+ch] to get some compiler optimization.

6
  • Hope-based optimization doesn't make any sense really. You can make a pointer byte*[] but it's probably not what you intend to have - look in the docs. Commented Dec 11, 2013 at 10:12
  • @BartoszKP Maybe you're right, I'm probably over-optimizing! My point is that in C/C++, well made declarations give often better performance (and legibility) against heavy code, as compiler can optimize former but not latter. Commented Dec 11, 2013 at 10:29
  • In C# this is the recommended way to work with bitmaps in terms of performance. Commented Dec 11, 2013 at 10:56
  • I know, but I'm trying to get a clearer code using pointer to array. Commented Dec 11, 2013 at 11:20
  • 3
    In your question you say that you want to "get some compiler optimization", not "get a clearer code". Make up your mind, you can't have both. Commented Dec 11, 2013 at 11:21

1 Answer 1

7
+25
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FastPixel
{
    public readonly byte R;
    public readonly byte G;
    public readonly byte B;
}


private static void Main()
{
    unsafe
    {
        // 8-bit.
        byte[] b1 =
        {
            0x1, 0x2, 0x3,
            0x6, 0x7, 0x8,
            0x12, 0x13, 0x14
        };


        fixed (byte* buffer = b1)
        {
            var fastPixel = (FastPixel*) buffer;
            var pixelSize = Marshal.SizeOf(typeof (FastPixel));

            var bufferLength = b1.Length / pixelSize;
            for (var i = 0; i < bufferLength; i++)
            {
                Console.WriteLine("AVERAGE {0}", (fastPixel[i].R + fastPixel[i].G + fastPixel[i].B)/pixelSize);
            }
        }
    }
}

}

This should be pretty much identical what you have. Note that I don't expect any performance gains. This is not micro-optimization, it's nano-optimization.

If dealing with huge images, look into parallel programming & SSE and how cache lines work(they have saved me actually 3-4 seconds - crazy right?!)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, but that's what I'm actually using. I'm looking for an array pointer, so I don't even need do define a struct.
About optimization gain: I will benchmark b1[x*3+ch] against fastpixel[x].R to check...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.