12

私は大まかに次のロジックで重要なコードを書いています

if(expression is true){
   //do something with extremely low latency before the nuke blows up. This branch is entered rarely, but it is the most important case
}else{
   //do unimportant thing that doesnt really matter
}

式の周りにマクロを使用することを考えているlikely()ので、それが重要なブランチに到達したときに、最小のレイテンシーが得られます。

私の質問は、プリフェッチする可能性の低いブランチを選択しているため、マクロ名が示唆する使用法とは正反対です。つまり、重要なブランチが発生する可能性は低いですが、発生した場合に最も重要なことです。

パフォーマンスの観点からこれを行うことの明らかな欠点はありますか?

4

2 に答える 2

9

はい。コンパイラが高速化することを期待して、可能性は低いが高速である必要がある分岐をあたかも可能性の高い分岐であるかのようにタグ付けすることで、コンパイラをだましています。

それを行うことには明らかなマイナス面があります — あなたが何をしているのか、そしてその理由を説明する良いコメントを書かないと、6 か月後に何人かのメンテナー (おそらくあなた自身) はほぼ確実にこう言うでしょう:可能性が高いブランチを間違ったブランチに置き、それを「修正」します。

また、可能性ははるかに低いですが、まだ可能性のあるマイナス面もあります。現在または将来使用する一部のコンパイラのバージョンが、可能性の高いマクロで期待していたものとは異なることを行い、それらの異なることがあなたが望んでいたものではないということです。コンパイラをだまして実行させると、ループを実行するたびに、元に戻す前にリアクターのシャットダウンの 90% を投機的に 10 万ドルを費やすコードになってしまいます。

于 2012-06-06T21:44:24.710 に答える
4

これは、マクロの意味で使用される __builtin_expect(x, 1) の従来の使用法とはまったく逆です。

#define likely(x) __builtin_expect(x, 1)

これは個人的には悪い形だと思います (パフォーマンスが向上する可能性が高いとは思えないパスを不可解にマークしているため)。ただし、 __builtin_expect(x) はパスを「似ている」と主張することでニーズを想定していないため、この最適化をマークすることもできます。これは単なる標準的な使用方法です。

#define optimize_path(x) __builtin_expect(x, 1)

これは同じことを行いますが、可能性の低いパスを可能性が高いと非難するコードを作成するのではなく、実際に試みていることをコードに記述して、クリティカルパスを最適化します。

ただし、核兵器のタイミングを計画している場合は、コンパイルされたアセンブリを手動でチェック (およびタイミング) して、タイミングが正しいようにするだけでなく、RTOS も使用する必要があります。より高速なプロセッサを使用するか、予測ミスの遅延を正しく調整するだけで、「100 万分の 1」のイベントを補償できるため、分岐の予測ミスの影響は非常に小さいため、ここではほとんど不要です。最新のコンピューターのタイミングに影響を与えるのは、OS のプリエンプションとスケジューリングです。非常に離散的な時間スケールで何かを行う必要がある場合は、ほとんどの汎用オペレーティング システムが持つ疑似リアルタイムではなく、リアルタイムでスケジュールする必要があります。一般に、分岐の予測ミスは、RT 状況で RTOS を使用しない場合に発生する可能性のある遅延よりも数百倍小さくなります。通常、分岐の予測ミスが問題になる可能性があると思われる場合は、分岐予測子の状態が複雑で制御できないため、時間に敏感な問題から分岐を削除します。マクロの「可能性が高い」および「可能性が低い」は、さまざまな領域からヒットする可能性があり、さまざまな分岐予測状態で、最も重要なことに、非常に頻繁に使用されるコードのブロック用です。これらのブランチにヒットする頻度が高いため、それを使用するアプリケーション (Linux カーネルなど) のパフォーマンスが明らかに向上します。枝に 1 回しか当たらない場合は、通常、分岐予測子には、複雑で制御できない状態があるためです。マクロの「可能性が高い」および「可能性が低い」は、さまざまな領域からヒットする可能性があり、さまざまな分岐予測状態で、最も重要なことに、非常に頻繁に使用されるコードのブロック用です。これらのブランチにヒットする頻度が高いため、それを使用するアプリケーション (Linux カーネルなど) のパフォーマンスが明らかに向上します。枝に 1 回しか当たらない場合は、通常、分岐予測子には、複雑で制御できない状態があるためです。マクロの「可能性が高い」および「可能性が低い」は、さまざまな領域からヒットする可能性があり、さまざまな分岐予測状態で、最も重要なことに、非常に頻繁に使用されるコードのブロック用です。これらのブランチにヒットする頻度が高いため、それを使用するアプリケーション (Linux カーネルなど) のパフォーマンスが明らかに向上します。枝に 1 回しか当たらない場合は、これらのブランチにヒットする頻度が高いため、それを使用するアプリケーション (Linux カーネルなど) のパフォーマンスが明らかに向上します。枝に 1 回しか当たらない場合は、これらのブランチにヒットする頻度が高いため、それを使用するアプリケーション (Linux カーネルなど) のパフォーマンスが明らかに向上します。枝に 1 回しか当たらない場合は、場合によっては 1 ナノ秒のパフォーマンス向上が得られる可能性がありますが、アプリケーションがそれほどタイム クリティカルである場合、パフォーマンスを大幅に向上させるためにできることは他にもあります。

于 2012-10-05T15:45:57.440 に答える