6

私はこのコード行を持っています:

 base_num = (arr[j]/base)%256;

この行はループで実行され、操作「/」および「%」は実行に多くのリソースと時間を要します。プログラムのパフォーマンスを最大化するために、この行を変更してビット演算を適用したいと思います。どうやってやるの?

ありがとう。

4

3 に答える 3

7

baseが2のn乗の場合、除算をnの右へのビットシフトに置き換えることができます。次に、整数のmod 256を取得することは、最後の8ビットを取得することと同等であるため、0xFFとANDすることができます。または、256 * baseとANDをとってから、nを右にビットシフトすると、操作を逆にすることができます。

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

もちろん、中途半端なコンパイラなら誰でもこれを実行できるはずです。

于 2012-11-26T16:46:48.400 に答える
3

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

gccでは、ドキュメントによると、どちらが-O1オンになりますか?-ftree-slsr

樹木に対して直線的な強度低減を実行します。これは、乗算を含む関連する式を認識し、可能な場合はそれらをより安価な計算に置き換えます。

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

于 2012-11-26T16:49:12.100 に答える
1

base_num8ビット整数として宣言することもできます。

#include <stdint.h>

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

コンパイラが標準の補完である場合、byte(0xFF00)0x00)の値をに入れますbase_num

プレーンC(C ++でもC#でもない)で飽和演算を実行するコンパイラーにはまだ会っていませんが、そうすると、の値が、sat_byte(0xFF00)より大きい値0xFFになり0xFFますbase_num

この場合、コンパイラは精度の低下を警告することに注意してください。この場合、コンパイラがエラーになる可能性があります(Visual StudioはTreat Warnings as ErrorsOnを使用します)。それが起こった場合、あなたはただすることができます:

base_num = (uint8_t)crap;

しかし、これはあなたが避けようとしていることのようです。

あなたがやろうとしているのは、除算が必要であり、除算が最もコストのかかる基本的な算術演算であるため、モジュラス演算子を削除することです。「インテリジェント」コンパイラ(デバッグモードでも)が次のように「最適化」するため、私は通常、これをボトルネックとは考えていません。

base_num = crap & 0xFF;

サポートされているプラ​​ットフォーム(私が聞いたすべての主流プロセッサ-x86、AMD64、ARM、MIPS)で、これはどのようなものでもかまいません。基本的なANDおよびOR算術命令を持たないプロセッサについて聞いて、私は呆然とします。

于 2012-11-26T16:53:38.330 に答える