ARM9 プロセッサ用のロギング C コードを書いています。動的モジュールが存在する場合、このコードはいくつかのデータを記録します。モジュールは通常、製品ビルドには存在しませんが、ロギング コードは常にコンパイルされます。これは、顧客がバグに遭遇した場合に、このモジュールをロードすると、ロギング コードがデバッグ情報をダンプするという考え方です。
モジュールが存在しない場合、ロギング コードは最小限の影響しか与えない必要があるため、すべてのサイクルがカウントされます。一般に、ロギング コードは次のようになります。
__inline void log_some_stuff(Provider *pProvider, other args go here...)
{
if (NULL == pProvider)
return;
... logging code goes here ...
}
最適化をオンにすると、RVCT 4.0 は次のようなコードを生成します。
ldr r4,[r0,#0x2C] ; pProvider,[r0,#44]
cmp r4,#0x0 ; pProvider,#0
beq 0x23BB4BE (usually taken)
... logging code goes here...
... regular code starts at 0x23BB4BE
このプロセッサには分岐予測子がありません。私の理解では、分岐が行われるたびに 2 サイクルのペナルティがあります (分岐が行われなければペナルティはありません)。
一般的なケースであるNULL == pProviderが、分岐が行われない高速なケースであることを望みます。RVCT 4.0 でこのようなコードを生成するにはどうすればよいですか?
私は__builtin_expect次のように使用してみました:
if (__builtin_expect(NULL == pProvider, 1))
return;
残念ながら、これは生成されたコードには影響しません。私は__builtin_expect間違って使用していますか?別の方法はありますか (できればインライン アセンブリなし)。