バイナリ データのメモリ ブロックをバイト単位で実行しています。
現在、私は次のようなことをしています:
for (i = 0; i < data->Count; i++)
{
byte = &data->Data[i];
((*byte & Masks[0]) == Masks[0]) ? Stats.FreqOf1++; // syntax incorrect but you get the point.
((*byte & Masks[1]) == Masks[1]) ? Stats.FreqOf1++;
((*byte & Masks[2]) == Masks[2]) ? Stats.FreqOf1++;
((*byte & Masks[3]) == Masks[3]) ? Stats.FreqOf1++;
((*byte & Masks[4]) == Masks[4]) ? Stats.FreqOf1++;
((*byte & Masks[5]) == Masks[5]) ? Stats.FreqOf1++;
((*byte & Masks[6]) == Masks[6]) ? Stats.FreqOf1++;
((*byte & Masks[7]) == Masks[7]) ? Stats.FreqOf1++;
}
マスクの場所:
for (i = 0; i < 8; i++)
{
Masks[i] = 1 << i;
}
(ループやインライン関数でどうにかして高速に実行できなかったので、書き出しました。)
この最初のループを改善する方法について何か提案はありますか? 私はビットに到達することにかなり慣れていません。
これは愚かなことのように思えるかもしれません。しかし、私は圧縮アルゴリズムを実装中です。ビットアクセス部分を右下にしたいだけです。
ありがとう!
PS: これは Visual Studio 2008 コンパイラに含まれています。したがって、提案がそのコンパイラに適用されるとよいでしょう。
PPS: 2 つのカウントをインクリメントする必要がないことに気付きました。1つで十分です。次に、最後に合計ビット数との差を計算します。しかし、それはカウントするだけに固有のものです。私が本当に早くしたいのは、ビット抽出です。
編集: 持ち出されたルックアップ テーブルのアイデアは素晴らしいです。タイトルで間違った質問をしたことに気づきました。最終的に私がやりたいことは、ビットを数えるのではなく、各ビットにできるだけ速くアクセスすることだからです。
別の編集: データ内でポインタを 1 ビットだけ進めることは可能ですか?
別の編集: これまでのすべての回答に感謝します。
次のステップで実装したいのは、コンテキストを分析しない単純なバイナリ算術コーダーです。だから私は今のところ単一のビットにしか興味がありません。最終的には Context-adaptive BAC になりますが、それについては後で説明します。
1 バイトではなく 4 バイトを処理することもできます。しかし、32 ビットのループもコストがかかりますね。