動的メモリ割り当てに関するスレッドの競合
-
29-09-2019 - |
質問
私はそれをC言語で学んだばかりです malloc
関数には、マルチスレッドアプリケーションで使用される場合、スレッド競合の問題が伴います。
C ++では operator new
同じ問題に苦しんでいますか?はいの場合、アプリケーションのパフォーマンスに大きなペナルティのように聞こえるこれを回避するためにどのようなテクニークを使用できますか?
解決
スレッド競合の「問題」は、実際には実装に依存します。一般的な使用におけるMallocの実装の一部は、もともとマルチスレッドを念頭に置いて設計されたものではありませんでした。しかし、マルチスレッドアプリケーション向けに設計されたMALLOC実装は、通常の状況では競合に悩まされるべきではありません。
マルチスレッドを念頭に置いて設計されたmalloc実装の例として、 jemalloc.
他のヒント
新しいものの実装に応じて、通常はmallocベースのyesです。ここであなたができることはほとんどありません:
- プロファイラーを使用して、通話の数をカウントします
malloc()
(そして多分brk()
)1秒あたり、競合の問題があることを確認してくださいmalloc()
. - 並列メモリアロケーター(つまり、並列メモリアロケーターを使用してみてください。 買いだめ)
- 可能な限りスタックを使用してください。必要でないときは新しい電話をかけないでください。また、小さなコピーは通常、スレッド間で共有されるポインターやデータよりもキャッシュに優しいものであることを忘れないでください。
C ++では、オペレーターは同じ問題に苦しんでいますか?
はい、ほとんどの実装では、そうです。
すでにC ++にいる場合は、 ビルディングブロックをスレッディングします ニーズに合ったC ++テンプレートライブラリです。スケーラブルなアロケーター、データ構造、a Webサイト もっと...
Mallocでのスレッド競合の問題は、単に、ヒープが更新されるたびに同様のデバイスのミューテックスによって保護されなければならないということです。 2つのスレッドがヒープを同時に更新すると、人種状態が発生します。同じ問題が新しいものに当てはまるため、次の問題よりも競合が少ない根本的な理由はありません。
そうは言っても、競合を最小限に抑えるためのいくつかのトリックがあります。 1つ目は、ヒープを別々のアリーナに分割することです。各アリーナには独自のロックがあります。スレッドがメモリの割り当てを試み、1つのアリーナがロックされている場合、次のアリーナから割り当てようとします。
フリーは、マロックに使用されたのと同じアリーナにアクセスする必要があります。これは、ポインターを無料リストに解放する場所によって最適化することもできます。これは原子的に行うことができます。次にアリーナがロック解除されると、無料リストのすべてのポインターが適切に解放されます。
これらの手法は、プロデューサーの消費者スレッディングモデルでは、消費者パスポインターをプロデューサーに戻すことができ、必要に応じて再利用または削除できることを意味する競合を防ぐのに役立ちますが、競合を排除しません。