問題:アトミック命令によるマップアクセスの安全性を保証するには、2つの異なるアトミックで命令の並べ替えが可能ですか?
私はリソースと呼ばれるstd::map
のオブジェクトを持っています。リソースは、リソース内のメンバーのセット/取得操作をサポートするオブジェクトです。また、set OR get操作は、パフォーマンス重視の他の多くのことを行います。 マップ自体からリソースを削除する操作もサポートする必要があります。したがって、set/get操作でリソースオブジェクトが実行されている可能性があります。リソース自体が削除され、メモリが破損する可能性があります。 リソースの削除操作は非常にまれです。 10億回にも及ぶ。
スレッドの一貫性を実現するためにpthread読み書きロックを使用しようとしましたが、パフォーマンスに影響します。後でこの問題を解決するためにアトミックを試みました。ここにコードがあります。
std::atomic<bool> g_changeInProgress{false}; // used to block all reader threads
std::atomic<int> g_readers{0}; // used to block delete thread
リーダースレッド
LOOP:
while(g_changeInProgress) {
std::this_thread::yield(); // give opportunity to schedule to other threads
}
g_readers++;
if(g_changeInProgress) {
g_readers--;
goto LOOP;
}
// DO SET/GET opration with the resource
// this portion should not execute in parallel to delete
g_readers--;
削除スレッド
g_changeInProgress = true;
while(g_readers) {} // busy loop untill no readers left
/* Delete the Resource here */
g_changeInProgress = false;
このコードスニペットは、私のために罰金と読み書きロックのpthreadよりもはるかに高速に動作するようです。 質問:スレッドを削除するには、コンパイラがこのコードをひどく失敗させるような命令を並べ替える可能性はありますか?
これより軽いアトミックロックの実装は可能ですか?
これらのビジーループは*ひどい*です。利回りは、他のスレッドが得られない可能性があるため、役に立たない。とりわけ、CPUリソースを浪費して、クロールを待っているスレッドを遅くすることがあります。そして、最悪の場合、最終的に待機を止めると、最悪の場合に誤った予測分岐が発生し、最悪の場合に大きなパフォーマンスペナルティが発生します。あなたがパフォーマンス* at * * all *を気にしているなら、このようなリモートでもコードを書いてはいけません。 –
@DavidSchwartz洞察をいただきありがとうございます。私のユースケースでは、削除が来たときにパフォーマンスを妥協するのは大丈夫です。そのまれなイベントです。このコードを使用するのはまだ良い考えではないと思いますか?即興化の提案はありますか? – piyush
あなたのリーダースレッドは同じ問題を抱えて同じループをしています。このすべての複雑さの根拠は何ですか? 「収穫」がどれくらい重いか分かりますか?そして、それは何にも降伏するものがなければ事態を悪化させます。 –