0

ループで実行するよりも高速な short[] の各 short を左シフト (ビット単位) するメソッド (c#/.net) はありますか?

デジタル カメラ (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

私はそれを行うライブラリメソッドを知りませんが、役立つかもしれないいくつかの提案があります。これは、ピクセルの上位4ビットが(ガベージではなく)確実にゼロであることがわかっている場合にのみ機能します。(ゴミの場合は、以下にビットマスクを追加する必要があります)。基本的に私は提案します:

  • より大きなデータ型(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 に答える