C#/ .net按位向左移位操作超短[]

时间:2011-05-16 00:45:43

标签: c# .net bit-manipulation shift

是否有一种方法(在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);
            }
        }
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分: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);
      }
    }
  }
}