0

是否有一种方法(在 c#/.net 中)可以左移(按位)short[] 中的每个短路,这比在循环中执行更快?

我说的是来自数码相机(16 位灰色)的数据,相机只使用低 12 位。所以要在渲染数据时看到一些东西,它需要向左移动 4。

到目前为止,这就是我正在做的事情:

byte[] RawData; // from camera along with the other info

if (pf == PixelFormats.Gray16)
{
    fixed (byte* ptr = RawData)
    {
        short* wptr = (short*)ptr;
        short temp;

        for (int line = 0; line < ImageHeight; line++)
        {
            for (int pix = 0; pix < ImageWidth; pix++)
            {
                temp = *(wptr + (pix + line * ImageWidth));
                *(wptr + (pix + line * ImageWidth)) = (short)(temp << 4);
            }
        }
    }
}

有任何想法吗?

4

1 回答 1

2

我不知道可以做到这一点的库方法,但我有一些可能会有所帮助的建议。仅当您知道像素的高四位绝对为零(而不是垃圾)时,这才有效。(如果它们是垃圾,您必须在下面添加位掩码)。基本上我会建议:

  • 在较大的数据类型(int 或 long)上使用移位运算符,以便一次移动更多数据
  • 摆脱循环内的乘法运算
  • 做一个小循环展开

这是我的代码:

using System.Diagnostics;

namespace ConsoleApplication9 {
  class Program {
    public static void Main() {
      Crazy();
    }

    private static unsafe void Crazy() {
      short[] RawData={
        0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, 0x777, 0x888,
        0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff, 0x123, 0x456,

        //extra sentinel value which is just here to demonstrate that the algorithm
        //doesn't go too far
        0xbad 
      };

      const int ImageHeight=2;
      const int ImageWidth=9;

      var numShorts=ImageHeight*ImageWidth;

      fixed(short* rawDataAsShortPtr=RawData) {
        var nextLong=(long*)rawDataAsShortPtr;

        //1 chunk of 4 longs
        // ==8 ints
        // ==16 shorts
        while(numShorts>=16) {
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;

          numShorts-=16;
        }

        var nextShort=(short*)nextLong;
        while(numShorts>0) {
          *nextShort=(short)(*nextShort<<4);
          nextShort++;
          numShorts--;
        }
      }

      foreach(var item in RawData) {
        Debug.Print("{0:X4}", item);
      }
    }
  }
}
于 2011-05-16T01:38:48.100 回答