Darryl Gove、2011年12月
実行環境とは関係なく、パラレル化を有効に活用するためには、コードが正しく、予測どおりの結果が得られるようにしなければなりません。 この記事では、Oracle Solaris Studioのスレッド・アナライザを使用して、パラレル・コードが正しいかどうかを分析する方法について説明します。
|
今日、SPARCやx86と同等の多くのプロセッサは、複数のコアを装備しており、複数の同時実行スレッドをサポートできるようになっています。 また、多くのシステムで複数のマルチコア・プロセッサが採用されています。 選択したプラットフォームで最大限の価値とパフォーマンスを引き出すには、これらの複数のコアを利用し、複数の実行スレッドを活用することが重要です。
Oracle Solarisオペレーティング・システムには、効率的でスケーラブルなスレッド・モデルとスマートなスケジューラが用意されており、さまざまなアプリケーション開発ツールと配置ツールを使ってアプリケーションにリソースを提供できます。
既存のコードの大半は、パラレルの実行スレッドを想定せずに記述されています。 Oracle Solaris Studioのコンパイラには、アプリケーションが複数のスレッドを実行するためのメカニズムが用意されており、ユーザーはどのように実行するかを指定する必要がありません。 特に、ループでは、以前の繰り返しのシリアル処理を複数の個別の実行スレッドに分割できる場合が多くあります。
以下のコンパイラ・フラグをOracle Solaris Studioのコンパイラと組み合わせて使用すると、自動パラレル化処理を制御できます。
-xautopar
コンパイラ・フラグを使用します。-xloopinfo
コンパイラ・フラグを使用します。-xreduction
コンパイラ・フラグを使用します。また、自動パラレル化またはOpenMPのコンパイラ・フラグを使用してパラレル化したコードのスレッド数を管理するには、実行時にOMP_NUM_THREADS
環境変数を設定します。
Oracle Solaris StudioでOpenMP 3.1がサポートされるということは、パラレル・バージョンのアプリケーションを構築するために、コンパイラを使ってソース・コード内のディレクティブ(プラグマ)を検索できるということです。 自動パラレル化と同様に、コンパイラによって処理されるため、ユーザーはスレッドを管理する必要がありません。
OpenMPでは、きめ細かく実行することが可能な段階的なアプローチを行って、パラレル化を実現できます。 OpenMPを使用すると、他のループは変更せずに、スレッド処理によって最適化する特定のループに対してディレクティブを設定できます。 この他に、このアプローチにはまったく同じコード・ベースからシリアル・バージョンのアプリケーションとパラレル・バージョンのアプリケーションを取得できるという大きな利点もあり、このことはデバッグに役立ちます。
以下のOpenMP関連のコンパイラ・フラグをOracle Solaris Studioとともに使用します。
-xopenmp
コンパイラ・フラグを使用します。 OpenMPディレクティブは、このフラグを使用している場合のみ認識されます。-xvpara
コンパイラ・フラグを使用します。-xloopinfo
コンパイラ・フラグを使用します。また、OpenMPのコンパイラ・フラグまたは自動パラレル化を使ってパラレル化したコードの必要なスレッド数を管理するには、実行時にOMP_NUM_THREADS
環境変数を設定します。 デフォルトのスレッド数は2です。
POSIXスレッドAPIにプログラムを作成すると、アプリケーションにおけるスレッド使用を完全に制御できます。 POSIXスレッド(Pthreadsとも呼ばれます)の仕様には、一連のCプログラミング言語のタイプ、関数、および定数を定義した、スレッドAPIのPOSIX標準が示されています。 Oracle Solaris Studioのコンパイラは、POSIXスレッド・プログラミング・モデルをサポートしています。
Pthreads APIの詳細について、詳しくは『Oracle Solaris 11 Reference Manual』の「man pages section 3: Library Interfaces and Headers」に記載された「pthread.h
(3HEAD)」を参照してください。
Oracle Solaris Studioのスレッド・アナライザは、マルチスレッド・アプリケーションの正確さを確保するために設計されています。 特に、スレッド・アナライザは、マルチスレッド・アプリケーションで生じる可能性がある次の状況を検出、分析、およびデバッグするのに役立ちます。
データ・レース状態とデッドロック状態を検出するには、次の手順を実行してコードをコンパイルし、コンパイルしたコードをcollect -r all
コマンドを使用して実行し、スレッド・アナライザにロードします。
-xinstrument=datarace
コンパイラ・フラグを使用してアプリケーションをコンパイルします。 行番号とコール・スタック情報が正しく返されるように、-g
フラグも設定して、最適化レベルは使用しないことをお勧めします。または、Oracle Solaris Studio 12.3のコンパイラを使ってコンパイルした既存のバイナリがある場合は、コマンドdiscover -i datarace -o a.out.instrumented a.out
を使用して既存のバイナリを利用できます。
collect -r all
オプションを使用して、得られたアプリケーション・コードを実行し、実行プロセスでデータ・レース検出機能とデッドロック検出機能を作成します。 作成した機能の名前はtha.1.er
になります。または、次のコマンドを使用して、アプリケーション・コードを実行し、データ・レース検出機能のみを作成します。
% collect -r race <app> <params>
または、次のコマンドを実行して、アプリケーション・コードを作成し、デッドロック検出機能のみを作成します。
% collect -r deadlock <app> <params>
tha tha.1.er
を実行して、作成した機能をスレッド・アナライザにロードし、データ・レース状態とデッドロック状態を特定します。 図1に、スレッド・アナライザのRacesタブを示します。図1. スレッド・アナライザを使用したデータ・レース状態の特定
スレッド・アナライザを使用すると、ソース・コード内でレース状態に関連している個々の行を特定できます(図2)。
図2. スレッド・アナライザを使用した、ソース・コード内のデータ・レース状態に関連している個々の行の特定
コンパイラ・フラグとオプションについて、詳しくはOracle Solaris Studioの完全な製品ドキュメントを参照してください。
次のドキュメントも参照してください。
リビジョン1.0、13.12.11 |
Facebook、Twitter、またはOracle Blogsで最新情報をご確認ください。