SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Intel TBBの並列コンテナによる安全でスケーラブルな並列処理

マルチコアへの移行を容易にする並列コンテナクラスの利用

安全でないコンテナの使用を検知する

 この例をMicrosoft Visual Studio .NET 2005でコンパイルし、4プロセッサのIntel Xeonサーバー上で4つのスレッドによって実行してください。そうすれば、何か問題があることがすぐに分かるでしょう。31行目によって報告される合計値が実行のたびに変わり、決してN(1000000)と等しくなりません。競合状態やその他のスレッド化エラーがあるのかもしれません。

 この点を確認するため、潜在的なデータ競合やデッドロックやその他のスレッド化エラーを検出するツール(Intel Thread Checker)でこの例を実行してみました。Intel Thread Checkerにより、スレッド間の潜在的な依存関係を検知し、その依存関係をエラーの元になっているソース行にマップすることができました。これらの潜在的な依存関係は、すべて同じ箇所(8行目)を指していました。これは、スレッドがSTLのmapにアクセスするところです(図1を参照)。

図1 Intel Thread Checkerツールは依存関係を検知して、潜在的な競合を容易に取り除けるようにする
図1 Intel Thread Checkerツールは依存関係を検知して、潜在的な競合を容易に取り除けるようにする

スケーラブルなソリューションを見つける

 図1を見ると、mapへのアクセスを同期化する必要があることが明らかになります。まず、単一のWin32 MutexまたはCRITICAL_SECTIONオブジェクトを使ってアクセスを監視する処理のパフォーマンスを調べます。既に述べたように、粒度の粗い同期は、スレッドセーフでないライブラリを使ってスレッドセーフを保証する唯一の方法です。

 Win32 Mutexは全プロセスから見えるカーネルオブジェクトです。単一のMutexオブジェクトでSTLのmapへの各アクセスを監視すれば、スレッドセーフが保証されますが、そうするとオーバーヘッドも非常に大きくなります。それに対し、Win32 CRITICAL_SECTIONは軽量で、ユーザー空間のプロセス内ミューテックスオブジェクトなので、こちらの方が好ましい選択肢です。

 図2に、STLのmapを使って同期化を行うバージョンのパフォーマンスを、同じコードをシーケンシャルに実装した場合を1として示します。

図2 3つのオプションのいずれも許容できるパフォーマンスをもたらさない
図2 3つのオプションのいずれも許容できるパフォーマンスをもたらさない

 同期がなければ、STLのmapは良好なパフォーマンスをもたらしますが、同時アクセスが行われると問題が起き、誤った結果を引き起こします。Win32 Mutexはコストが高いため、予想どおり劣悪なパフォーマンスをもたらします。単一のCRITICAL_SECTIONオブジェクトと粒度の粗い同期を用いた場合も、パフォーマンスは低下します。スレッドセーフなSTL mapベースの実装は、どちらも元のシーケンシャルな実装よりも実行時間が長くなります。粒度の粗い同期は正確さを復活させますが、同時並行性がないためスケーラビリティが低下します。

 図3は、STLのmapをTBBのconcurrent_hash_mapに置き換えたときのパフォーマンスを示しています。

図3 Intel TBBのconcurrent_hash_mapはSTLのmapのパフォーマンスを向上させる
図3 Intel TBBのconcurrent_hash_mapはSTLのmapのパフォーマンスを向上させる

 concurrent_hash_mapを使用する場合のパフォーマンスと、STLのmapで同期を行わない場合のパフォーマンスとを比較すると、Intel TBBによって実現されるスレッドセーフにはそれなりに代償が伴うことが明らかになります。しかしこの実装は、他のスレッドセーフな実装とは異なり、1よりも大きなスピードアップをもたらすだけの同時並行性を実現します。

 つまり、TBBの並列コンテナの同時並行性を利用すると、安全でないコンテナに粒度の粗いロックを適用する方法ではとても実現できない高いパフォーマンスが可能になります。

 これからはますます多くの開発者が、マルチコアシステムへの移行という避けがたい事態に直面することになるでしょう。こうした開発者にとっては、マルチスレッドアプリケーション開発でエラーを起きにくくするためのツールを探求することが絶対必要になります。TBBに含まれている並列コンテナクラスもそうしたものの1つであり、マルチコアへの移行を容易にしてくれます。これらの並列コンテナクラスが提供する安全でスケーラブルな実装のおかげで、C++ STLで定義されているようなスレッドフレンドリでないコンテナを使わずに済み、このようなコンテナに伴う諸々の問題を回避できるからです。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Michael Voss(Michael Voss)

Intel社のSenior Staff Software Engineer。2001年にPurdue大学からElectrical Engineering博士号を授与された。現在、IntelのThreading LabとToronto大学の非常勤講師を掛け持つ。平行プログラミングとコンパイラの最適化に...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/873 2007/01/29 00:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー