さまざまなプラットフォームでintおよびlongの場合、より速くまたは遅いですか?Interlocked.Incrementの性能
答えて
アクションが原子的に強制され、メモリバリアとして機能し、メモリの並べ替えの機能を排除します命令の回りにアクセスする。
スレッド間で共有できるアクションをアトミックオン状態にするには、Interlocked.Incrementを使用する必要があります。これは、x ++を完全に置き換えるものではありません。
レジスタを更新するだけでCPUバスロックを実行する必要があるため、常に遅くなります。しかし、現代のCPUはレジスタの性能に近づくため、リアルタイム処理でも無視できます。
X86 CPUはInterlockedオペレーション中にBuslockを実行しますが、Interlockedオペレーションを提供するすべてのCPUではBuslockは必要ありません。いくつかのCPUは、単一のキャッシュラインを予約し、バスブロックなしでそのキャッシュライン上でインターロック動作を実行できることを信号で伝えることができます。 – Adisak
遅いです。しかし、スカラー変数に対するスレッドの安全性を達成するために私が知っている最も一般的な一般的な方法です。
'volatile'はスカラー上でより優れていますが、うまく使用するには良いコーディング方法が必要であるという欠点があります。 – Abel
揮発性で注意してください。いくつかのプロセッサアーキテクチャ(x86/x64)は、そのメモリがコンパイラに対して揮発性とマークされているかどうかにかかわらず、メモリへのアクセスを並べ替えることができます。 –
すぐに考えてみてください。Increment
の呼び出しは、インクリメント演算子の単純なアプリケーションより速くはできません。その場合、インクリメント演算子のコンパイラの実装は内部でIncrement
を呼び出し、同じことを実行します。
しかし、あなた自身でテストしても分かるように、同じことはしません。
2つのオプションは目的が異なります。増分演算子は一般的に使用してください。演算をアトミックにする必要がある場合はIncrement
を使用し、その変数の他のすべてのユーザーもインターロック操作を使用していることを確認してください。 (それらがすべて協力しているわけではない場合は、実際には役に立ちません)
いいえ、そうではありません - Interlocked.Incrementはプロパティで呼び出すことはできませんが、++演算子は呼び出すことができません。したがって、++はそれを呼び出すことができません。 – SLaks
より正確に言えば、Incrementはref int(またはlong)をとります。 ++は非ref int(またはlong)をとります – SLaks
コンパイラはインクリメントで++を実装できます。単純な "call"命令では実装されませんが、コンパイラによって導入された一時的な命令を使用して実行できます。要点は、コンパイラが空き領域を利用して数値をインクリメントするという方法です。より高速なものがあれば、コンパイラは代わりにそれを使用していました。 –
私たちの経験では、Windows上のInterlockedIncrement()などは非常に大きな影響を与えています。あるサンプル事例では、インターロックをなくし、代わりに++/- を使用することができました。これにより、実行時間が140秒から110秒に短縮されました。私の分析では、インターロックがメモリ往復を強制する(そうでなければ、他のコアがどのようにそれを見ることができるか)。 L1キャッシュの読み取り/書き込みは約10クロックサイクルですが、メモリの読み書きは100ほどです。
このサンプルのケースでは、約10億回の増分/減算操作の回数を予測しました。したがって、2Ghz CPUの場合、++/- の場合は5秒、インターロックの場合は50秒です。その差をいくつかのスレッドに広げ、その差を30秒に近づけます。
Micrsoft氏:InterlockedIncrementは、http://msdn.microsoft.com/en-us/library/windows/desktop/ee418650(v=vs.85).aspxで36-90サイクルかかると測定されました。 – Lothar
疑問の余地なく操作、私はコアi7の重い争いの操作の約120回を測定しているが、多分私はそれをボットした? L1キャッシュの読み書きは約10クロックサイクルです... " - そのページを変更してマークし、L1からメモリにフラッシュするだけで十分です別のコアがそれを見る必要がある場合、コンプライアンスのない操作は、100 +ではなくスペクトルの10の端(36に近い)に近いことがあります。 –
私もパフォーマンステスト:
揮発性:65174400
ロック:連動62428600
:113248900
TimeSpan span = TimeSpan.FromSeconds(5);
object syncRoot = new object();
long test = long.MinValue;
Do(span, "volatile",() => {
long r = Thread.VolatileRead(ref test);
r++;
Thread.VolatileWrite(ref test, r);
});
Do(span, "lock",() =>
{
lock (syncRoot)
{
test++;
}
});
Do(span, "interlocked",() =>
{
Interlocked.Increment(ref test);
});
「Do」とは何ですか? – SLaks
時間が経過するまでn回メソッドを実行します – MastsrOfDesaster
だから、もっと待ち時間が増えますか?あなたのメトリックは何ですか? –
- 1. VB ++の演算子++ Interlocked.Increment
- 2. 性能特性
- 3. Java enumsの可用性の可能性と可能性?
- 4. GWTuploadの性能
- 5. GCCの性能
- 6. as3の性能
- 7. グリッドコンポーネントの性能
- 8. wkhtmltopdfの性能
- 9. Rubyの性能
- 10. Luceneの性能
- 11. JavaScriptの性能
- 12. CPUの性能
- 13. JRubyの性能
- 14. Logglyの性能
- 15. OpenMPの性能
- 16. Ettercapの性能
- 17. グラフデータベースの性能
- 18. SerialPortの性能
- 19. jsonの性能
- 20. Iterrowsの性能
- 21. Rubyのクラス依存性の可能性
- 22. boost :: signals2の性能
- 23. ヘーゼルキャストIMapの性能
- 24. Javascriptギャラリーの性能
- 25. テーブルデザインの可能性
- 26. Pythonマルチプロセッシングの性能
- 27. C# - Comboboxの性能
- 28. Boost Pythonの性能
- 29. Haskell Regexの性能
- 30. nodejs-opencvの性能
他の人が指摘するように、それは同じことではありません。それはhttp://msdn.microsoft.com/en-us/magazine/cc163726.aspxによると、Interlocked.Incrementは14nS(または約1秒あたり約7000分の1)かかるので、私はあまり心配しませんパフォーマンスについて – smirkingman
Interlocked.Incrementはスレッド環境で使用することを意図しています – EProgrammerNotFound