0

フラグが設定されているときに変数の値を変更したいとします。明らかな方法は次のとおりです。

int a = 1, b = 2;
if(Flag)
    {
    a=b;
    Flag = false;
    }

ただし、これは、操作を実行するために生成されたコードでは非常に非効率的です。私は、以下が操作を実行するために40%少ないコードを生成することを発見しました。

a = ((!Flag)*a)+((Flag)*b);
Flag = false;

私の質問:乗法/除算演算子はターゲットでの実行が遅いため、乗法「*」演算子は使用しません。コードスペースを増やすことなくこれを高速化するために他に何を使用できますか?

編集:ターゲットデバイスは、kHz範囲で実行されているMSP430です。コードスペースと実行時間は重要です。コンパイラはIARCです

4

4 に答える 4

1

コンパイラは、このハックよりもコードを最適化できます(生成されたアセンブリを確認してください)。比較が遅いプロセッサ(PowerPCなど)を除いて、それは避ける必要があります。とにかく、まだやる気があればここを見てください。

于 2012-10-22T17:18:11.823 に答える
1

以下は、乗算や条件を使用せずに、目的のロジックを実現します。

unsigned int mask = Flag-1;
a = (mask & a) | (~mask & b);

したがって、Flag == 1の場合、次のようになります。

a = (0x0 & a) | (0xffff & b);

Flag == 0の場合、次のようになります。

a = (0xffff & a) | (0x0 & b);

(マスク用に個別の変数も実際には必要ありません。代わりに実行--Flagして使用することができます。ソリューションが少し明確になると思いました。)Flagmask

于 2012-10-22T17:28:49.617 に答える
1

マイクロ最適化について何も考えずに、このように書きます。

int b = 2, a = Flag ? b : 1;

Flag = false;

それがどれほど効率的か見てみましょう。

于 2012-10-22T18:30:52.610 に答える
0

あなたの最初のコードはそれが得るのと同じくらい効果的です。他のあいまいな難読化を使用してより効果的なコードを生成できる場合は、コンパイラの最適化が正しく構成されていないか、正しく記述されていません。前者の可能性が高いですが、後者の場合は、コンパイラが不正なコードを生成する理由をIARに尋ねてください。難読化されたコードを記述してコンパイラを修正しようとしないでください。

条件付きの?:演算子を使用する必要はありません。まったく同じコードを生成する必要があります。

さらに、MSP430についてはよくわかりませんが、平均16ビットであり、高度な命令キャッシュや分岐予測はありません。MSP430があると思った場合にのみ、自分をだましていることになります。たとえあったとしても、コードを難読化してはいけません。

于 2012-10-22T19:28:12.950 に答える