「マシン」モードでは、すべてのスレッドのネイティブな呼び出しスタックと、コンパイラによって生成されたアウトライン関数が表示されます。
OpenMPプロファイルデータ、マシン表現 プログラムの実行のさまざまな局面における実際の呼び出しスタックは、前述の直感的なモデルに示したものとは大きく異なります。マシンモードでは、呼び出しスタックが測定どおりに表示され、変換は行われず、擬似関数も構築されません。ただし、時間プロファイルのメトリックスは依然として示されます。
次に示す各呼び出しスタックでは、libmtsk は OpenMP ランタイムライブラリ内の呼び出しスタックに入っている 1 つ以上のフレームを表しています。どの関数がどの順序で表示されるかの詳細は、バリア用のコードまたは縮小を行うコードの内部的な実装と同様に、OpenMP のリリースによって異なります。
最初の並列領域の前
最初の並列領域の前最初の並列領域に入る前の時点で存在するスレッドは、マスタースレッドただ 1 つだけです。呼び出しスタックはユーザーモードおよび上級モードの場合と同じです。
|
マスター |
|---|
|
foo |
|
main |
|
_start |
並列領域内で実行中
|
マスター |
スレーブ 1 |
スレーブ 2 |
スレーブ 3 |
|---|---|---|---|
|
foo-OMP... | |||
|
libmtsk | |||
|
foo |
foo-OMP... |
foo-OMP... |
foo-OMP... |
|
main |
libmtsk |
libmtsk |
libmtsk |
|
_start |
_lwp_start |
_lwp_start |
_lwp_start |
マシンモードでは、スレーブスレッドはマスターが開始された _start 内ではなく、_lwp_start 内で開始されたものとして示されます。一部のバージョンのスレッドライブラリでは、この関数は _thread_start として表示されます。foo-OMP... の呼び出しは、並列領域に対して生成された mfunction を表します。
すべてのスレッドがバリアの位置にある
|
マスター |
スレーブ 1 |
スレーブ 2 |
スレーブ 3 |
|---|---|---|---|
|
libmtsk | |||
|
foo-OMP... | |||
|
foo |
libmtsk |
libmtsk |
libmtsk |
|
main |
foo-OMP... |
foo-OMP... |
foo-OMP... |
|
_start |
_lwp_start |
_lwp_start |
_lwp_start |
スレッドが並列領域内で実行されるときと異なり、スレッドがバリアの位置で待機しているときは、foo と並列領域コード foo-OMP... の間に OpenMP ランタイムからのフレームは存在しません。その理由は、実際の実行には OMP 並列領域関数が含まれていませんが、OpenMP ランタイムがレジスタを操作し、スタック展開で直前に実行された並列領域関数からランタイムバリアコードへの呼び出しが示されるようにするからです。そうしないと、どの並列領域がバリア呼び出しに関連しているかをマシンモードで判定する方法がなくなってしまいます。
並列領域から出たあと
|
マスター |
スレーブ 1 |
スレーブ 2 |
スレーブ 3 |
|---|---|---|---|
|
foo | |||
|
main |
libmtsk |
libmtsk |
libmtsk |
|
_start |
_lwp_start |
_lwp_start |
_lwp_start |
スレーブスレッド内では、呼び出しスタック上にユーザーフレームが存在しません。
入れ子の並列領域内にいるとき
|
マスター |
スレーブ 1 |
スレーブ 2 |
スレーブ 3 |
スレーブ 4 |
|---|---|---|---|---|
|
bar-OMP... | ||||
|
foo-OMP... |
libmtsk | |||
|
libmtsk |
bar | |||
|
foo |
foo-OMP... |
foo-OMP... |
foo-OMP... |
bar-OMP... |
|
main |
libmtsk |
libmtsk |
libmtsk |
libmtsk |
|
_start |
_lwp_start |
_lwp_start |
_lwp_start |
_lwp_start |