Score-Pを用いたプログラムの性能計測

最終更新: 2018.08.03 

このページに記載されているサービスは試験的なものであり、TSUBAMEの正式なサポート範囲には含まれません。
このページのスクリーンショット等にはTSUBAME2時代のものが含まれています。

性能計測(プロファイリング・トレーシング)とは

プログラムの性能が想定どおりに出ていないときには、どの部分で時間がかかっているのかや、どのような処理(演算・メモリアクセス・通信など)がボトルネックになっているのかを調べて、起こっている状況にあわせてプログラムを改善していく必要があります。そのためには、プログラム中に計測用のルーチンを埋め込み、その出力を逐一解析する必要がありますが、このような測定作業は性能計測ツールを用いることで自動化することができます。

マニュアルおよび参考資料

本文書執筆時点での最新の計測ツールのマニュアルは以下のとおりです。

また、開発者らによる以下のスライド(英語)が参考になるかと思います。

環境設定

TSUBAME3の各種ソフトウェアと同様に module load で必要なモジュールをロードしてください。
Score-PおよびScalascaはMPIおよびCUDAの組み合わせに一部バイナリが依存しています。モジュールロード時にエラーとなった際には、利用したいMPI環境、CUDAバージョンを添えてお問い合わせからご連絡ください。

Score-Pを用いた計測対象プログラムのコンパイル

計測対象のプログラムをコンパイルする際には、コンパイラのコマンドの前にscorepを付加してください。たいていの場合はMakefileの変数を変更することで対応できます。

Makefile変更例: CC = scorep icc

MPI, OpenMP, CUDAを組み合わせて利用している場合で、コマンドラインから利用しているものが判別できない場合には、scorepに--mpp=mpi, --thread=omp, --cudaの各オプションを付加することで明示的にそれらへの対応を有効にすることができます。

Makefile変更例: LD = scorep --cuda mpicxx

Score-Pによる性能計測の実行

前節でscorepコマンドを付加してコンパイルしたバイナリを普段どおりに実行すると、scorepで始まるディレクトリ(任意の名前に設定可能)が作成され、そのなかに計測結果が出力されます。計測はプロファイリング(実行時間などの割合を関数ごとに取得する)とトレース(時系列でどのような処理が行われたかを取得する)に大別できますが、まずは実行時間およびストレージへのオーバヘッドが小さいプロファイリングを行うことをお勧めします。
Score-pにおける計測の条件はSCOREPで始まる環境変数で変更可能です。以下に一部の例を示します。

環境変数 デフォルト 効果
SCOREP_ENABLE_PROFILING true falseにするとプロファイリングが無効になる
SCOREP_ENABLE_TRACING false trueにするとトレーシングが有効になる
SCOREP_TOTAL_MEMORY (自動) 計測に用いるメモリ容量
トレース取得時には大きめにする必要がある
SCOREP_EXPERIMENT_DIRECTORY (自動) 計測結果出力ディレクトリ名
指定しない場合scorepで始まる時刻に基づいた名前になる
SCOREP_METRIC_PAPI (なし) カンマ区切りで指定されたパフォーマンスカウンタをPAPIを用いて取得する
SCOREP_FILTERING_FILE (なし) ファイル上で指定された関数を計測対象から外す

 全環境変数の解説は以下のコマンドで表示することができます。

$ scorep-info config-vars --full

OpenMPIを利用する際には、下記の例のように、指定した環境変数の一覧を mpirun の -x オプションに渡す必要があります、MPICH, MVAPICH2の場合は必要ありません。

$ mpirun -np ${NP} -hostfile ${PBS_NODEFILE} -x SCOREP_ENABLE_PROFILING -x SCOREP_ENABLE_TRACING ./a.out

性能プロファイルの可視化

SCOREP_ENABLE_PROFILING(デフォルトで有効)が有効にされた状態で実行すると、出力ディレクトリ内にprofile.cubexというファイルが出力されます。X転送を有効にした状態(sshコマンドの-Yオプションを利用してください)でcubeコマンドを用いるとこのファイルの内容を表示することができます。

$ cube scorep-XXXX/profile.cubex

以下のような画面が表示されます。

Scalasca スクリーンショット

左側のペインで表示したい指標(関数の実行回数、累積実行時間、通信量、PAPIカウンタなど)を選択し、中央のペインで関数のコールツリーを表示、右側のペインでノード・プロセス・スレッドごとの計測値を表示できます。

性能トレースの可視化

SCOREP_ENABLE_TRACINGを有効にした状態で実行すると、出力ディレクトリ内にtraces.otf2というファイルが出力されます。X転送を有効にした状態で(sshコマンドの-Yオプションを利用してください)以下のコマンドを実行すると、取得したトレースファイルを読みこんで可視化することができます。

$ vampir scorep-XXXX/traces.otf2

以下のような画面が開きます。

Vampir スクリーンショット

並列プログラムのプロセス・スレッドごとに、以下のような指標を得ることができます。

  • ユーザプログラム・MPI通信・OpenMP並列化部分・GPU処理・計測オーバヘッドなどの割合
  • 選択した任意の関数に関する情報(実行開始・終了時刻、関数名など)
  • Communication Matrix(MPI送信ランク・受信ランク毎のメッセージ量)
  • PAPIによるハードウェアカウンタの値
  • メモリ使用量

計測対象の最適化

デフォルトの設定でトレースを取得しようとすると、末端の小さな関数の計測にかかる時間・メモリのためにプログラムの挙動が変化してしまうことがあります。対策としては、SCOREP_FILTERING_FILEを用いて計測対象となる関数を除く方法と、scorepによる計測関数の自動挿入をやめて手動で計測区間を入れる方法があります。ここでは前者の方法について説明します、手動での計測区間の挿入についてはScore-Pのマニュアルを参照してください。

計測関数ごとのオーバヘッドの表示

cube_scoreコマンドを用いると、各ルーチンごとにトレースを取得したときに必要とされるメモリ量(≒プロファイル・トレース取得時のオーバヘッド)を表示することができます。

% scorep-score -r scorep-XXXX/profile.cubex
[...]
flt type   max_buf     visits     time %time region
    ALL 5372038254 1634100763 12406.32 100.0 ALL
    USR 5358738138 1631138913  5873.05  47.3 USR
    OMP   12389148    2743808  6465.96  52.1 OMP
    COM     673610     185320     8.31   0.1 COM
    MPI     237358      32722    58.99   0.5 MPI
    USR  716505830  522844416  2068.66  16.7 binvcrhs_
    USR  716505830  522844416  1788.68  14.4 matmul_sub_
    USR  716505830  522844416  1787.72  14.4 matvec_sub_
    USR   76195080   22692096    75.07   0.6 binvrhs_
    USR   76195080   22692096    93.68   0.8 lhsinit_
    USR   56825184   17219840    59.24   0.5 exact_solution_
    OMP     738072     102912     0.74   0.0 !$omp parallel @exch_qbc.F:244
    OMP     738072     102912     0.73   0.0 !$omp parallel @exch_qbc.F:255
[...]

この中で、占める割合の大きいもの(visits(呼び出し回数)の多い、計測対象にするには細かすぎる関数など)を計測対象から外すことで、計測のオーバヘッドを軽減することができます。上記の例では例えば以下のようなフィルタファイルを作成してください。

% cat scorep.filt
SCOREP_REGION_NAMES_BEGIN EXCLUDE
binvcrhs*
matmul_sub*
matvec_sub*
exact_solution*
binvrhs*
lhs*init*
timer_*
SCOREP_REGION_NAMES_END

このフィルタファイルへのパスをSCOREP_FILTERING_FILEに与えることで、指定された関数を計測対象から除くことができます。また、cube_scoreコマンドに-fオプションでこのファイルを与えることで、フィルタを適用したときのメモリ消費をシミュレートすることができます。

(参考)Scalascaによる通信の詳細プロファイリング

Scalascaを経由してScore-Pを用いることにより、late send, late receiveなど、通信のタイミングに関してより詳細に解析することができます、詳細は本文書冒頭のリンク先の資料をご覧ください。