算術演算が何らかの理由でメモリアクセスより速い場合は、ルックアップテーブルよりも速くなる可能性があります。これは、計算がベクトル化される(PPC AltiVecまたはIntel SSE)場合、および/またはプログラムの他の部分がキャッシュメモリのすべてのビットを使用する必要がある場合に可能です。
膨張係数= 3の場合は、わずか7の命令が必要とされている:
out = (((in * 0x101 & 0x0F00F) * 0x11 & 0x0C30C3) * 5 & 0x249249) * 7;
または他の代替、10の命令で:他の膨張係数> = 3の場合
out = (in | in << 8) & 0x0F00F;
out = (out | out << 4) & 0x0C30C3;
out = (out | out << 2) & 0x249249;
out *= 7;
:
unsigned mask = 0x0FF;
unsigned out = in;
for (scale = 4; scale != 0; scale /= 2)
{
shift = scale * (N - 1);
mask &= ~(mask << scale);
mask |= mask << (scale * N);
out = out * ((1 << shift) + 1) & mask;
}
out *= (1 << N) - 1;
またはその他の代替、拡張係数> = 2の場合:
unsigned mask = 0x0FF;
unsigned out = in;
for (scale = 4; scale != 0; scale /= 2)
{
shift = scale * (N - 1);
mask &= ~(mask << scale);
mask |= mask << (scale * N);
out = (out | out << shift) & mask;
}
out *= (1 << N) - 1;
shift
およびmask
ビットストリーム処理の前に値を計算する方がよい。
8ビットの値しか扱っていない場合は、ルックアップテーブルがほぼ確実に最適なオプションになります。それは非常に小さなスペースを使用します。あなたのユースケースとあなたが一般的であると予想される操作の詳細を教えてください。 – templatetypedef
入力は一定のシリアルビットストリームです。現在の要件では、データの各チャンクは一度に8バイトずつ到着します。その後、3ビットずつ拡張して各ビットを別のビットストリームとして送出する必要があります。 192bitsで64bits。将来の要件は、それぞれの拡張された8ビット値の前に "ヘッダ"ビットを追加し、もちろんバイト境界にパディングすることを含むかもしれない。 LUTは速いですが、どれくらいの頻度で実行する必要があるかを考えれば、パフォーマンスの向上が期待できます。 – jivany
多くのアーキテクチャには、この種の計算を大幅に高速化できる命令があります。これらの命令を活用してプラットフォーム間の互換性を崩すことを恐れていない場合は、ほぼ確実に勝つことができます。アルゴリズム的に "些細な"ものを最適化する場合は、低レベルの最適化を行うことが重要です。 @Kaganar合意。 – Kaganar