2012-11-26 5 views
6

私はこのコードの行を持っています。私はこの行を変更し、プログラムのパフォーマンスを最大にするためにビット操作を適用したいと思います。どうやってやるの?モジュル演算子と除算演算子を置き換えるビット演算の使い方は?</p> <pre><code>base_num = (arr[j]/base)%256; </code></pre> <p>この行は、ループ内で実行され、オペレーション「/」と「%」リソースおよび実行するために多くの時間を取る:

ありがとうございました。

+0

は '定数をbase'であるか、それが変化していますか? – Xymostech

+9

コンパイラは何も価値があるならば、それはそれは ''%よりも高速ですすべてのプラットフォーム上で '&0xFF'と'%を256単位に置き換えられます。 'base'の価値は何ですか? 基地=(INT)POW(256、(フロート)I);: –

+0

あなたが塩基変化の8ビット(符号なし)整数 –

答えて

7

基数が2のn乗である場合、その分母を右にnのビットシフトで置き換えることができます。その後、整数のmod 256を取ることは最後の8ビットを取ることと等価であるため、0xFFでANDをとることができます。あるいは、もしあなたが256 * baseでそれをANDし、次に右側にビットシフトするならば、操作を逆にすることができます。

base_num = arr[j] >> n; 
base_num &= 0xFF; 

もちろん、半二重のコンパイラであれば、これを行うことができます。

+1

'n'ビットでシフトする必要があります。' 2^n'は '1 << n'です。 –

+1

【支配カーネル(http://www.kernel.org)の 'pow'関数((http://ftp.gnu.org/gnu/glibc/)のglibc]からが上で定義されています(簡体字)のように: '(ベース== 2){場合のリターン(1つの<< EXP)}'そうだね –

+0

、私はそれを修正します:) –

3

-O1以上をコンパイラオプションに追加すると、コンパイラがそれを行います。 GCCで

は、-O1

木に直線強度低下を実行し、ドキュメントによれば、-ftree-slsrをオンにします。これは、乗算を伴う関連する式を認識し、可能な場合にはそれほど高価でない計算に置き換える。

これはモジュロと置き換えられ、定数であればベースとなります。ただし、基数が2の定数でないことがわかっている場合は、その数値のlog2を返すように周囲のコードをリファクタリングして、その数値から1を引いた>>を得ることができます。

1

また、単に8ビット整数としてbase_numを宣言することができます:

#include <stdint.h> 

uint8_t base_num; 
uint16_t crap; 
crap = 0xFF00; 
base_num = crap; 

あなたのコンパイラが標準賛辞である場合、それはbase_numbyte(0xFF00)0x00)の値を入れます。

私は、プレーンC(どちらもC++やC#)で算術を飽和んコンパイラを満たすためにまだ持っているが、それがない場合、それは0xFFより大きいこと、それはbase_num0xFFを置くsat_byte(0xFF00)の値を入れます。

この場合、コンパイラは精度の低下を警告します。この場合、コンパイラでエラーが発生することがあります(Visual StudioではTreat Warnings as Errorsがオンになります)。その場合、あなただけ行うことができます。

base_num = (uint8_t)crap; 

が、これはあなたが避けるようにしようとしているもののように思えます。

あなたがしようとしているのは、除算と除算が最もコストのかかる基本的な算術演算であるため、係数演算子を削除するようです。私がしまし対応プラットフォーム(すべての主流のプロセッサ上で

base_num = crap & 0xFF; 

:(でも、デバッグモードでの)任意の「インテリジェント」コンパイラはそれを「最適化」と同じように、私は一般的にどのような方法でボトルネックと考えるではないでしょう - x86、AMD64、ARM、MIPS)のいずれかであるはずです。私は基本的なANDおよびOR算術命令を持たないプロセッサのことを聞くために唖然とするだろう。

関連する問題