Oracle® Solaris Studio 12.4: パフォーマンスアナライザ

印刷ビューの終了

更新: 2015 年 1 月
 
 

ハードウェアカウンタプロファイリングデータ

ハードウェアカウンタは、キャッシュミス、キャッシュストールサイクル、浮動小数点演算、分岐予測ミス、CPU サイクル、および実行対象命令といったイベントの追跡に使用されます。ハードウェアカウンタ プロファイリングでは、スレッドが実行されている CPU の指定されたハードウェアカウンタがオーバーフローしたときに、コレクタによってプロファイルパケットが記録されます。この場合、そのカウンタはリセットされ、カウントを続行します。プロファイルパケットには、オーバーフロー値とカウンタタイプが入っています。

さまざまなプロセッサチップファミリが、2 ~ 18 個の同時ハードウェアカウンタレジスタをサポートしています。コレクタは、複数のレジスタ上でデータを収集できます。レジスタごとに、オーバーフローをモニターするカウンタの種類を選択したり、カウンタの オーバーフロー値 を設定したりすることができます。ハードウェアカウンタには、任意のレジスタを使用できるものと、特定のレジスタしか使用できないものがあります。このことは、1 つの実験であらゆるハードウェアカウンタの組み合わせを選択できるわけではないことを意味します。

また、ハードウェアカウンタプロファイリングは、パフォーマンスアナライザおよび er_kernel ユーティリティーを使用してカーネルに対して実行することもできます。詳細は、Chapter 9, カーネルプロファイリングを参照してください。

パフォーマンスアナライザは、ハードウェアカウンタプロファイリングデータをカウントメトリックに変換します。周期的にカウントするカウンタの場合、報告されたメトリックが時間に変換されます。周期的にカウントしないカウンタの場合、報告されるメトリックはイベントカウントです。複数の CPU を搭載したマシンの場合、メトリックの変換に使用されるクロック周波数が個々の CPU のクロック周波数の調和平均となります。プロセッサのタイプごとに専用のハードウェアカウンタセットがあり、またハードウェアカウンタの数が多いため、ハードウェアカウンタメトリックはここに記載していません。ハードウェアカウンタリストでは、どのような種類のハードウェアカウンタがあるかについて調べる方法を説明します。

「cycles」と「insts」の 2 つの特定のカウンタが収集される場合、「CPI」と「IPC」という 2 つのメトリックが使用可能になり、これらはそれぞれ「命令当たりのサイクル数」と「サイクル当たりの命令数」を意味します。これらは常に比率として表示され、時間、カウント、あるいはパーセントで示されません。CPI 値が高いか IPC 値が低ければ、マシン内でのコードの実行が非効率であることを示し、逆に CPI 値が低いか IPC 値が高ければ、パイプライン内で実行中のコードの効率がよいことを示します。

ハードウェアカウンタの用途の 1 つは、CPU に出入りする情報フローに伴う問題を診断することです。たとえば、キャッシュミス回数が多いということは、プログラムを再構成してデータまたはテキストの局所性を改善するか、キャッシュの再利用を増やすことによってプログラムのパフォーマンスを改善できることを意味します。

ハードウェアカウンタはほかのカウンタと関連する場合があります。たとえば、分岐予測ミスが発生すると、間違った命令が命令キャッシュにロードされるため、分岐予測ミスと命令キャッシュミスが関連付けられることがよくあります。これらは正しい命令に置き換える必要があります。置換により、命令キャッシュミス、命令トランスレーションルックアサイドバッファー (ITLB) ミス、またはページフォルトが発生する可能性があります。

多くのハードウェアカウンタでは、オーバーフローイベントを引き起こした命令のあとの 1 つ以上の命令でオーバーフローが発生することがよくあります。この状況は「スキッド」と呼ばれ、カウンタオーバーフロープロファイルの解釈を困難にすることがあります。

最新の SPARC プロセッサでは、一部のメモリーベースのカウンタ割り込みは的確であり、トリガーイベントの PC (プログラムカウンタ) および有効なアドレスを使用して提供されます。このようなカウンタは、イベントタイプのあとの precise というワードで示されます。メモリー領域とデータ領域のデータがこれらのカウンタに対してデフォルトで取得されます。詳細は、データ領域プロファイリングとメモリー領域プロファイリングを参照してください。

ハードウェアカウンタリスト

ハードウェアカウンタはプロセッサ固有であるため、どのカウンタを利用できるかは、使用しているプロセッサによって異なります。 パフォーマンスツールには、よく使われると考えられるいくつかのカウンタの別名が用意されています。現在のマシン上でほかのどの引数も指定せずに collect -h を実行することによって、現在のマシン上でのプロファイリングのためのハードウェアカウンタ定義の最大数を確認したり、使用可能なハードウェアカウンタの完全なリストやデフォルトのカウンタセットを表示したりすることができます。

プロセッサとシステムがハードウェアカウンタプロファイリングをサポートしている場合、collect -h コマンドは、ハードウェアカウンタに関する情報を含む 2 つのリストを出力します。最初のリストには、一般的な名称に別名が設定されたハードウェアカウンタが含まれます。2 番目のリストには、raw ハードウェアカウンタが含まれます。パフォーマンスカウンタサブシステムにも collect コマンドにも特定システムのカウンタの名前がない場合、各リストは空になります。ただしほとんどの場合、カウンタは数値で指定できます。

次の例では、カウンタリストに含まれるエントリを示します。 別名が設定されたカウンタがリストの最初に表示され、続いて raw ハードウェアカウンタリストが表示されます。 この例の出力における各行は、印刷用の形式になっています。

Aliased HW counters available for profiling:
    cycles[/{0|1|2|3}],<interval> (`CPU Cycles', alias for Cycles_user; CPU-cycles)
    insts[/{0|1|2|3}],<interval> (`Instructions Executed', alias for Instr_all; events)
    loads[/{0|1|2|3}],<interval> 
     (`Load Instructions', alias for Instr_ld; precise load-store events)
    stores[/{0|1|2|3}],<interval> 
     (`Store Instructions', alias for Instr_st; precise load-store events)
    dcm[/{0|1|2|3}],<interval> 
     (`L1 D-cache Misses', alias for DC_miss_nospec; precise load-store events)
    l2l3dh[/{0|1|2|3}],<interval> 
     (`L2 or L3 D-cache Hits', alias for DC_miss_L2_L3_hit_nospec; precise load-store events)
    l3m[/{0|1|2|3}],<interval> 
     (`L3 D-cache Misses', alias for DC_miss_remote_L3_hit_nospec~emask=0x6; precise load-store events)
    l3m_spec[/{0|1|2|3}],<interval> 
     (`L3 D-cache Misses incl. Speculative', alias for DC_miss_remote_L3_hit~emask=0x6; events)
.
.
.
 Raw HW counters available for profiling:
    Sel_pipe_drain_cycles[/{0|1|2|3}],<interval> (CPU-cycles)
    Sel_0_wait[/{0|1|2|3}],<interval> (CPU-cycles)
    Sel_0_ready[/{0|1|2|3}],<interval> (CPU-cycles)
    Sel_1[/{0|1|2|3}],<interval> (CPU-cycles)
    Sel_2[/{0|1|2|3}],<interval> (CPU-cycles)
    Pick_0[/{0|1|2|3}],<interval> (CPU-cycles)
    Pick_1[/{0|1|2|3}],<interval> (CPU-cycles)
    Pick_2[/{0|1|2|3}],<interval> (CPU-cycles)
    Pick_3[/{0|1|2|3}],<interval> (CPU-cycles)
    Pick_any[/{0|1|2|3}],<interval> (CPU-cycles)
    Branches[/{0|1|2|3}],<interval> (events)
    Instr_FGU_crypto[/{0|1|2|3}],<interval> (events)
    Instr_ld[/{0|1|2|3}],<interval> (precise load-store events)
    Instr_st[/{0|1|2|3}],<interval> (precise load-store events)
別名が設定されたハードウェアカウンタリストの形式

別名が設定されたハードウェアカウンタリストでは、最初のフィールド (たとえば、cycles) は、collect コマンドの -h counter... 引数で使用できる別名を示します。この別名は、er_print コマンド内で使用する識別子でもあります。

2 番目のフィールドは、カウンタの使用可能なレジスタを示します。たとえば、[/{0|1|2|3}] のようになります。

3 番目のフィールド <interval> は、onhilow と指定するか、数値で指定します。onhi、または low と指定し、非常に急速にイベントが発生した場合、元のレートに減速します。

4 番目のフィールドは、括弧で囲まれ、タイプ情報を含んでいます。これは、簡単な説明 (たとえば、CPU Cycles)、raw ハードウェアカウンタ名 (たとえば、Cycles_user)、およびカウントされている単位の種類 (たとえば、CPU-cycles) を示します。

    種類情報フィールド内の可能性のあるエントリには次のものがあります。

  • precise である場合は、命令によってイベントカウンタがオーバーフローすると、カウンタ割り込みが正確に発生します。正確なカウンタに対する collect -h コマンドは、デフォルトでメモリー領域およびデータ領域のデータを収集します。詳細は、「データオブジェクト」ビュー「データレイアウト」ビュー、および「メモリーオブジェクト」ビューを参照してください。

  • loadstore、または load-store のいずれかである場合、そのカウンタはメモリーに関連したものです。

  • not-program-related である場合、カウンタはほかのプログラムによって開始されたイベント、たとえば CPU 対 CPU のキャッシュスヌープなどを取り込みます。プロファイリングにカウンタを使用すると、警告が生成され、プロファイリングで呼び出しスタックが記録されません。

    タイプ情報の最後のワードまたは唯一のワードが、

  • CPU-cycles である場合は、そのカウンタを使用して時間ベースのメトリックを提供できます。そのようなカウンタについて報告されるメトリックは、デフォルトでは包括的時間および排他的時間へ変換されますが、イベントカウントとして表示することもできます。

  • events である場合、メトリックは包括的および排他的イベントカウントであり、時間へ変換できません。

この例の別名が設定されたハードウェアカウンタリストでは、タイプ情報にワードが含まれており、最初のカウンタの場合は CPU-cycles で、2 番目のカウンタの場合は、events となっています。3 番目のカウンタでは、タイプ情報に load-store events という 2 つのワードが含まれています。

raw ハードウェアカウンタリストの形式

raw ハードウェアカウンタリストに含まれる情報は、別名設定されたハードウェアカウンタリストに含まれる情報のサブセットです。raw ハードウェアカウンタリスト内の各行には、cputrack(1) で使用された内部カウンタ名、そのカウンタを使用できるレジスタ番号、デフォルトのオーバーフロー値、タイプ情報、および CPU-cycles または events のどちらかのカウンタ単位が含まれています。

カウンタがプログラムの実行に関連のないイベントを測定する場合、タイプ情報の最初のワードは not-program-related になります。そのようなカウンタの場合、プロファイリングで呼び出しスタックが記録されませんが、その代わりに、擬似関数 collector_not_program_related で使用された時間が示されます。スレッドと LWP ID は記録されますが、意味がありません。

raw カウンタのデフォルトのオーバーフロー値は 1000003 です。この値はほとんどの raw カウンタで最適でないため、raw カウンタを指定する際にオーバーフロー値を指定する必要があります。