【问题标题】:Using pointer to array in unsafe C#在不安全的 C# 中使用指向数组的指针
【发布时间】:2013-12-11 10:06:48
【问题描述】:

在 C 中,我可以像这样定义一个指向数组的指针:

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

这样b3[i][j] == b1[i*3+j]

我可以在unsafe C# 中声明这样的指针b3 吗?

我的意图是访问位图通道:

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

我希望这样,使用source[x][ch]而不是source[x*3+ch]来获得一些编译器优化。

【问题讨论】:

  • 基于希望的优化真的没有任何意义。您可以创建一个指针byte*[],但这可能不是您想要的 - look in the docs
  • @BartoszKP 也许你是对的,我可能过度优化了!我的观点是,在 C/C++ 中,良好的声明通常会针对繁重的代码提供更好的性能(和易读性),因为编译器可以优化前者但不能优化后者。
  • 在 C# 中,this 是在性能方面使用位图的推荐方式。
  • 我知道,但我正在尝试使用指向数组的指针来获得更清晰的代码。
  • 在您的问题中,您说您想要“获得一些编译器优化”,而不是“获得更清晰的代码”。下定决心,你不能两者兼得。

标签: c# unsafe


【解决方案1】:
[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);
            }
        }
    }
}

}

这应该与您所拥有的几乎相同。请注意,我预计不会有任何性能提升。这不是微观优化,而是纳米优化。

如果处理巨大的图像,请研究并行编程和 SSE 以及缓存行的工作原理(它们实际上为我节省了 3-4 秒 - 很疯狂吧?!)

【讨论】:

  • 谢谢,但这就是我实际使用的。我正在寻找一个数组指针,所以我什至不需要定义一个结构。
  • 关于优化增益:我会将b1[x*3+ch]fastpixel[x].R 进行基准测试...
猜你喜欢
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 2023-03-18
  • 2017-08-25
相关资源
最近更新 更多