問題タブ [interlocked-increment]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
4 に答える
652 参照

c++ - InterlockedIncrement64 を使用した参照カウント オブジェクトのコピー コンストラクターの原子性

オブジェクトの参照カウントがスレッドセーフであることを確認する方法について頭を悩ませようとしています。

必要なクラス宣言がそこにあると仮定して、単純にしておきます。コピー コンストラクタとデストラクタの実装を次に示します。

このスレッドは安全ですか? アトミックかどうかに関係なく、コピー コンストラクターの intilization リストはどのように表示されますか? それも問題ですか?初期化リストでカウントの増分値を設定する必要がありますか (これは可能ですか)?

このままで十分です。そうでなけれthread1thread2count == 1. スレッド間でハンドシェイクが必要です。つまり、スレッド 1 は、スレッド 2 のオブジェクトが範囲外になる前にオブジェクトを完全にコピーする必要があります。

これらの回答のいくつかを読んだ後、私は戻って少し調査を行いました. Boost は、非常によく似たように shared_ptr を実装しています。これがデストラクタの呼び出しです。

ブーストのドキュメントでは、割り当てはスレッドセーフではないと明確に述べていると示唆する人もいます。私は同意し、同意しません。私の場合、私は同意しないと思います。スレッド A とスレッド B の間のハンドシェイクのみが必要です。いくつかの返信で説明されている問題のいくつかは、ここでは当てはまらないと思います (ただし、それらは私が完全には考えていない目を見張るような返信でしたが)。

例 ThreadA atach(SharedObject); //値で渡された共有オブジェクト、カウントの増分など

ThreadB //オブジェクトを受け入れ、共有オブジェクトのリストに追加します。ThreadB は、すべての SharedObjects にイベントを通知するタイマー上にあります。通知する前に、クリティカル セクションによって保護されたリストのコピーが作成されます。CS がリリースされ、コピーが通知されます。

ThreadA detach(SharedObject); //オブジェクトのリストから共有オブジェクトを削除します

現在、同時に ThreadB は SharedOjbect をシグナリングしており、ThreadA が共有オブジェクトをデタッチする前にリストのコピーを作成しています。すべて大丈夫ですよね?

0 投票する
1 に答える
341 参照

c++ - マルチスレッドループを手動で作成する-最適ではないスケーラビリティ

私はこのテストアプリケーションを作成しました。0から9999までの反復を経て、範囲内の整数ごとに、役に立たないが計算集約的な関数を計算します。その結果、プログラムは関数値の合計を出力します。複数のスレッドで実行するために、InterlockedIncrementを使用しています。増分後に反復回数が10000未満の場合、スレッドはこの反復を処理します。それ以外の場合は終了します。

なぜそれが私が望むほどスケーリングしていないのか疑問に思います。5スレッドの場合、1スレッドの場合は36秒であるのに対し、8秒で実行されます。これにより、最大4.5のスケーラビリティが得られます。OpenMPを使った実験中(わずかに異なる問題で)、スケーラビリティが大幅に向上しました。

ソースコードを以下に示します。

PhenomIIX6デスクトップでWindows7OSを実行しています。他にどのようなパラメータが関連しているのかわからない。

この最適ではないスケーラビリティについて説明していただけませんか。どうもありがとう。

編集:このテストプログラムのサンプル出力を添付します(1および5スレッド): ここに画像の説明を入力してください

0 投票する
7 に答える
10074 参照

c# - Interlocked.CompareExchange等値の代わりに GreaterThan または LessThan を使用する

このSystem.Threading.Interlockedオブジェクトでは、アトミック操作として加算 (減算) と比較が可能です。等価性だけでなく、アトミックな比較として GreaterThan/LessThan も行う CompareExchange は非常に価値があるようです。

仮説上Interlocked.GreaterThanの IL の機能ですか、それとも CPU レベルの機能ですか? 両方?

他のオプションがない場合、C++ またはダイレクト IL コードでそのような機能を作成し、その機能を C# に公開することは可能ですか?

0 投票する
1 に答える
2237 参照

c# - C#のSpinLock。どのタイプのアルゴリズムでSpinLockがMonitorに対してより良い選択ですか?

重複の可能性:
なぜ誰もがSpinLockの方が速いと言っているのですか?

この質問は、SpinLock、Monitor、およびInterlockedに関するものです。

のパフォーマンスをテストする2つのテストを行いましたが、Monitorこれらのテストで混乱しました。SpinLockInterlocked

SpinLock私の混乱は、特に本当にどれだけ速いかということです。私のテストによると、SpinLockより遅いですMonitor。しかし、多くのドキュメントや記事に基づいて、SpinLockパフォーマンスを向上させる必要があります。

そして今、どのシナリオSpinLockでパフォーマンスが向上するのだろうか?

以下に、私が実行したテストの詳細を示します。

最初のテストでは、非常に短い操作を実行して同じ共有ロックオブジェクトにアクセスするスレッドをいくつか作成しました(または操作をまったく実行しませんでした。これは単なるテストです)。

2番目のテストでは、要素の配列と、この配列内の要素にランダムにアクセスするいくつかのスレッドを作成しました。各要素には独自のロックオブジェクトが含まれています。テストの場合、テストのSystem.Objectオブジェクトの場合と同様に、スレッドは配列要素内のint型のパブリック変数を使用して操作を実行します。MonitorSpinLockSpinLockInterlocked.IncrementInterlocked.Increment

各テストでは、共有領域へのアクセスがループで実行されます。各テストは、次の3つのルーチンで構成されています。

  • SpinLockのテスト
  • テストモニター
  • Increment.Interlockedのテスト

各テストは、それSpinLockがより遅いことを示しましたMonitor。したがって、前述のテストを実行して以来、私が気になる質問は、どのシナリオがパフォーマンスの向上に適しているかということです。SpinLock


詳細を説明するために、テストのコードを投稿します。

(両方のテストは.net 4.5に対してコンパイルされました)

テスト1、スレッドは同じ共有ロックオブジェクトへの排他的アクセスを取得しようとしています

テスト2、スレッドは、ランダムに選択された配列の要素への排他的アクセスを取得しようとしています。つまり、競合の少ないテストを実行します。


追加テスト3.テストはシングルスレッドで実行されます。スレッドがロックにアクセスする可能性が最も高くなります。

私が理解している限り、3番目のテストがSpinLock選択の最良のケースです。競合はまったくありません。シングルスレッド-シーケンス実行。なぜSpinLockまだはるかに遅れているのMonitorですか?誰かが私にSpinLock(デバイスドライバーの開発を除いて)まったく役立つことを証明するコードを教えてもらえますか?

0 投票する
1 に答える
1764 参照

c# - C#でオブジェクトに一意のIDをパフォーマンス的に割り当てるにはどうすればよいですか?

私は通常の操作の一部として大量の小さなオブジェクトを作成するC#ライブラリに取り組んでいます(コンパイラのASTノードを考えてください)。パフォーマンスを妨げない方法で、各インスタンスに一意の識別子(プログラム内で一意であり、グローバルに一意ではない)を割り当てたいと思います。オブジェクトは不変であり、スレッド間で共有できるため、IDはスレッド間で一意である必要があります。

これが私が検討しているいくつかのオプションです:

  1. static intまたはlongを使用し、次の呼び出しを介して新しいIDを取得します。Interlocked.Increment()
  2. Guid.NewGuid()IDの生成に使用
  3. 属性でstaticintまたはlongフィールドを使用して[ThreadStatic]から、現在のスレッドのプロパティから文字列IDを作成しManagedThreadId、スレッドローカルカウンターから次の値を作成します。

これらの1つは、他よりもパフォーマンスが高くなりますか?これを行うためのより良い方法はありますか?

ありがとう!

編集:
私は簡単なベンチマークを実行し、次の結果を得ました:

  1. 0.19秒(intとlongは基本的に同じでした)
  2. 1.1秒
  3. 3.5秒

これは、を使用することを強く示しているようInterlockedです。Interlockedただし、マルチスレッドシナリオで速度が低下するリスクはありますか?

0 投票する
1 に答える
890 参照

c# - .netでの優先度の高い/低いスレッドの管理

シナリオは次のとおりです。優先度の高いスレッドによって中断される可能性のある優先度の低いスレッドがいくつかあります。優先度の高いスレッドが優先度の低いスレッドに一時停止を要求するたびに、それらはWait状態になります(まだ待機状態になっていない場合)。ただし、優先度の高いスレッドが優先度の低いスレッドが可能Resumeであることを通知する場合、優先度の低いスレッドは、優先度の低いスレッドに一時停止を要求したすべての優先度の高いスレッドが同意するまで再開しないでください。

Pause()これを解決するために、優先度の高いスレッドから優先度の低いスレッドへの呼び出しをカウンター変数で追跡しています。優先度の高いスレッドが優先度の低いスレッドにを要求するたびにPause()、カウンターの値が1ずつインクリメントされます。インクリメント後にカウンターの値が。の場合1は、スレッドがになかったことを意味するWaitので、状態に移行するように依頼しWaitます。それ以外の場合は、値をインクリメントしcounterます。逆に、優先度の高いスレッドが呼び出されると、値がデクリメントされます。デクリメント後に値がである場合は、優先度の低いスレッドが値をデクリメントできることを意味しResume()ます。counter0Resume

これが私の問題の単純化された実装です。ifステートメント内の比較操作Interlocked.XXXが正しくありません。

if(Interlocked.Increment(ref _remain)== 1)

、読み取り/変更および比較操作はアトミックではないため。

ここで何が欠けていますか?スレッド優先を使用したくありません。

0 投票する
0 に答える
907 参照

c++ - C++ を使用した Windows InterlockedIncrement64 の代替

アプリケーションでアトミック インクリメントに InterlockedIncrement64 を使用して、スレッド セーフであることを確認しています。私のコードは、C ランタイム ライブラリのみに基づいている必要があります。次の 2 つのメソッドを記述したアトミック クラスを使用することにしました。

最初の方法は問題ないと思います (これには確認が必要です)!、2 番目の方法は同じ結果を計算しましたが、マルチスレッドでテストされていませんが、高速です。2 番目の方法は私にとって疑わしいです。それらからのアドバイスが必要です。経験のある方。