アプリケーションのパラレル・パフォーマンスを最適化する方法

Oracle Solaris Studio 12.3

Darryl Gove、2011年12月


この記事では、自動パラレル化、OpenMPディレクティブのサポート、POSIXスレッドAPIのサポートを含め、Oracle Solaris Studioソフトウェアを使用してパラレル・アプリケーションを生成する技法について説明します。




はじめに

実行環境とは関係なく、パラレル化を有効に活用するためには、コードが正しく、予測どおりの結果が得られるようにしなければなりません。 この記事では、Oracle Solaris Studioのスレッド・アナライザを使用して、パラレル・コードが正しいかどうかを分析する方法について説明します。

ソフトウェアのダウンロード、フォーラムへの参加、この記事のようなさまざまな技術的How-To資料へのアクセスをご希望の場合は、OTNメンバーにご登録ください。 スパム・メールが送信されることはありません。

今日、SPARCやx86と同等の多くのプロセッサは、複数のコアを装備しており、複数の同時実行スレッドをサポートできるようになっています。 また、多くのシステムで複数のマルチコア・プロセッサが採用されています。 選択したプラットフォームで最大限の価値とパフォーマンスを引き出すには、これらの複数のコアを利用し、複数の実行スレッドを活用することが重要です。

Oracle Solarisオペレーティング・システムには、効率的でスケーラブルなスレッド・モデルとスマートなスケジューラが用意されており、さまざまなアプリケーション開発ツールと配置ツールを使ってアプリケーションにリソースを提供できます。

  • Oracle VM Server for x86、Oracle VM Server for SPARCなどの仮想化システムを使用すると、複数のオペレーティング・システム・インスタンスで1つの物理システムを共有できます。
  • スレッド形式のOracle Solarisコンテナにより、1つのオペレーティング・システム・インスタンス内に複数の実行環境を実現できます。
  • スレッド形式のアプリケーションにより、マルチコア・プロセッサおよびマルチソケット・システムで複数のコアを利用できます。

自動パラレル化の使用

既存のコードの大半は、パラレルの実行スレッドを想定せずに記述されています。 Oracle Solaris Studioのコンパイラには、アプリケーションが複数のスレッドを実行するためのメカニズムが用意されており、ユーザーはどのように実行するかを指定する必要がありません。 特に、ループでは、以前の繰り返しのシリアル処理を複数の個別の実行スレッドに分割できる場合が多くあります。

以下のコンパイラ・フラグをOracle Solaris Studioのコンパイラと組み合わせて使用すると、自動パラレル化処理を制御できます。

  • コード内で安全にパラレル化できるループを検索するようにコンパイラに指示するには、-xautoparコンパイラ・フラグを使用します。
  • コンパイラによってパラレル化したループに関する情報を生成するには、-xloopinfoコンパイラ・フラグを使用します。
  • すべての値を1つの配列に合計するなどの、さまざまな値を使用して1つの値を出力する縮約処理を検出してパラレル化するには、-xreductionコンパイラ・フラグを使用します。

また、自動パラレル化またはOpenMPのコンパイラ・フラグを使用してパラレル化したコードのスレッド数を管理するには、実行時にOMP_NUM_THREADS環境変数を設定します。

OpenMPのコンパイラ・フラグの使用

Oracle Solaris StudioでOpenMP 3.1がサポートされるということは、パラレル・バージョンのアプリケーションを構築するために、コンパイラを使ってソース・コード内のディレクティブ(プラグマ)を検索できるということです。 自動パラレル化と同様に、コンパイラによって処理されるため、ユーザーはスレッドを管理する必要がありません。

OpenMPでは、きめ細かく実行することが可能な段階的なアプローチを行って、パラレル化を実現できます。 OpenMPを使用すると、他のループは変更せずに、スレッド処理によって最適化する特定のループに対してディレクティブを設定できます。 この他に、このアプローチにはまったく同じコード・ベースからシリアル・バージョンのアプリケーションとパラレル・バージョンのアプリケーションを取得できるという大きな利点もあり、このことはデバッグに役立ちます。

以下のOpenMP関連のコンパイラ・フラグをOracle Solaris Studioとともに使用します。

  • OpenMPを有効にするには、-xopenmpコンパイラ・フラグを使用します。 OpenMPディレクティブは、このフラグを使用している場合のみ認識されます。
  • パラレル化に関する潜在的な問題をレポートするには、-xvparaコンパイラ・フラグを使用します。
  • パラレル化されたループに関する詳細情報を提供するようにコンパイラに指示するには、-xloopinfoコンパイラ・フラグを使用します。

また、OpenMPのコンパイラ・フラグまたは自動パラレル化を使ってパラレル化したコードの必要なスレッド数を管理するには、実行時にOMP_NUM_THREADS環境変数を設定します。 デフォルトのスレッド数は2です。

POSIXスレッドのサポート

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のスレッド・アナライザは、マルチスレッド・アプリケーションの正確さを確保するために設計されています。 特に、スレッド・アナライザは、マルチスレッド・アプリケーションで生じる可能性がある次の状況を検出、分析、およびデバッグするのに役立ちます。

  • データ・レースが原因で誤った結果や予測できない結果が発生したり、問題が発生していると思われる箇所から離れた場所で不定にデータ・レースが発生したりする可能性があります。 データ・レースは、以下の状況で発生します。
    • 1つのプロセス内の2つ以上のスレッドが同じメモリ位置に同時にアクセスしている
    • 少なくとも1つのスレッドが、書込みを実行するためにメモリ位置にアクセスしている
    • スレッドが、そのメモリへのアクセスを制御する排他ロックを使用していない  
  • デッドロック状態は、最初のスレッドが2番目のスレッドによって保持されたリソースを待機している状態でブロックされており、2番目のスレッドが最初のスレッドによって保持されたリソースを待機している状態でブロックされている場合(またはさらに多くの関連するスレッドが同様の状況)に発生します。

データ・レース状態とデッドロック状態を検出するには、次の手順を実行してコードをコンパイルし、コンパイルしたコードをcollect -r allコマンドを使用して実行し、スレッド・アナライザにロードします。

  1. -xinstrument=dataraceコンパイラ・フラグを使用してアプリケーションをコンパイルします。 行番号とコール・スタック情報が正しく返されるように、-gフラグも設定して、最適化レベルは使用しないことをお勧めします。

    または、Oracle Solaris Studio 12.3のコンパイラを使ってコンパイルした既存のバイナリがある場合は、コマンドdiscover -i datarace -o a.out.instrumented a.outを使用して既存のバイナリを利用できます。

  2. collect -r allオプションを使用して、得られたアプリケーション・コードを実行し、実行プロセスでデータ・レース検出機能とデッドロック検出機能を作成します。 作成した機能の名前はtha.1.erになります。

    または、次のコマンドを使用して、アプリケーション・コードを実行し、データ・レース検出機能のみを作成します。

    % collect -r race <app> <params>
    

    または、次のコマンドを実行して、アプリケーション・コードを作成し、デッドロック検出機能のみを作成します。

    % collect -r deadlock <app> <params>
    
  3. 最後に、コマンドtha tha.1.erを実行して、作成した機能をスレッド・アナライザにロードし、データ・レース状態とデッドロック状態を特定します。 図1に、スレッド・アナライザのRacesタブを示します。
図1

図1. スレッド・アナライザを使用したデータ・レース状態の特定

スレッド・アナライザを使用すると、ソース・コード内でレース状態に関連している個々の行を特定できます(図2)。

図2

図2. スレッド・アナライザを使用した、ソース・コード内のデータ・レース状態に関連している個々の行の特定

追加情報

コンパイラ・フラグとオプションについて、詳しくはOracle Solaris Studioの完全な製品ドキュメントを参照してください。

次のドキュメントも参照してください。

リビジョン1.0、13.12.11

FacebookTwitter、またはOracle Blogsで最新情報をご確認ください。