EN JA
PMC(3)
PMC(3) FreeBSD Library Functions Manual PMC(3)

名称

pmcハードウェアの性能のモニタリングカウンタにアクセスするためのライブラリ

ライブラリ

Performance Counters Library (libpmc, -lpmc)

書式

#include < pmc.h>

解説

Performance Counters Library (libpmc, -lpmc) は、アプリケーションが、特定のプロセスまたはシステム全体に関する性能データを集めるために、ハードウェア性能カウンタを使用できるプログラミングインタフェースを提供します。ライブラリは、 hwpmc(4) ドライバによって提供された低レベルの機能を使用して実装されています。

主要なコンセプト (概念)

性能モニタリングカウンタ (PMC) は、ソフトウェア抽象化を使用するライブラリによって表されます。これらの“abstract” PMC は、次の 2 つのスコープを持つことができます:
  • システムスコープ。これらの PMC は、全体のシステム様式、すなわち、現在実行しているスレッドと無関係に、イベントを測定します。システムスコープ PMC は、特定の CPU に割り付けられ、CPU の間を移動しません。特権がないプロセスは、 hwpmc(4) sysctl が調整可能であるなら、システムスコープ PMC を割り付けることができます: security.bsd.unprivileged_syspmcs は、0 以外です。
  • プロセススコープ。これらの PMC は、それらがアタッチされているプロセスが CPU で実行されているときだけ、ハードウェアイベントを測定します。 SMP システムでは、プロセススコープ PMC は、それらのターゲットプロセスとともに CPU の間を移動します。

PMC スコープと直交して、PMC は、2 つの操作上のモードの 1 つで割り付けられます:

  • PMC をカウントすることは、それらのスコープ (システムまたはプロセス) に従って、イベントを測定します。アプリケーションは、それらの値を検索するために明白にこれらのカウンタを読み込む必要があります。
  • PMC をサンプリングすることによって、CPU は、定期的に割り込まれ、実行の状態に関する情報を集めます。 PMC をサンプリングすることは、特定のプロセスとカーネルスレッドのプロファイルするため、またはシステム全体をプロファイルするために使用されます。

ソフトウェア PMC のためのスコープと操作上のモードは、PMC 割り付け時間に指定されます。アプリケーションは、ハードウェアリソースの利用可能性を前提として複数の PMC を割り付けることができます。

ライブラリは、ハードウェアによって測定されているイベントを名前付けするために人間に読み込み可能な文字列を使用します。 (もしあれば) 追加イベント特有の修飾子とともにハードウェアイベントを指定するために使用される構文は、下記のセクション イベント指定子 で詳細に説明されています。

PMC は、それらに割り付けられたプロセスに関連していて、プロセスが終了するとき、システムによって自動的に回収されます。さらに、プロセススコープ PMC は、それらが測定を実行できる前に、 1 つ以上のターゲットプロセスにアタッチされなければなりません。プロセススコープ PMC は、そうでなければ所有者のプロセスがデバッグすることが許可されている、それらのターゲットプロセスにアタッチされます。所有者のプロセスは、それ自身の振る舞いを測定するのを許可する PMC をそれ自体にアタッチします。さらに、いくつかのマシンアーキテクチャでは、そのような自己アタッチされた PMC は、プロセッサによってサポートされている特殊な命令を手軽に使用して読み込まれます。

PMC の特定の種類は、それらが開始される前に、ログファイルが設定されることを必要とします。これらは、次の通りです:

  • システムスコープサンンプリング PMC。
  • プロセススコープサンプリング PMC。
  • プロセスコンテキストスイッチ、またはプロセス終了時に、 PMC 読み込みを報告するために、設定されているプロセススコープカウンティング PMC。

最大 1 つのログファイルは、所有者プロセス毎に設定されます。その後、ログファイルにログ記録されたイベントは、 pmclog(3) 関数ファミリを使用して解析されます。

サポートされる CPU

PMC ライブラリで知られている CPU は、 enum pmc_cputype 列挙型によって指定されます。サポートされる CPU は、次の通りです:

PMC_CPU_AMD_K7
AMD Athlon CPU。
PMC_CPU_AMD_K8
AMD Athlon64 CPU。
PMC_CPU_INTEL_ATOM
Intel 性能測定アーキテクチャのバージョン 3 に準拠している Intel Atom CPU と他の CPU。
PMC_CPU_INTEL_CORE
Intel 性能測定アーキテクチャのバージョン 1 に準拠している Intel Core Solo と Core Duo CPU と他の CPU。
PMC_CPU_INTEL_CORE2
Intel 性能測定アーキテクチャのバージョン 2 に準拠している Intel Core2 Solo, Core2 Duo と Core2 Extreme CPU と他の CPU。
PMC_CPU_INTEL_P5
Intel Pentium CPU。
PMC_CPU_INTEL_P6
Intel Pentium Pro CPU。
PMC_CPU_INTEL_PII
Intel Pentium II CPU。
PMC_CPU_INTEL_PIII
Intel Pentium III CPU。
PMC_CPU_INTEL_PIV
Intel Pentium 4 CPU。
PMC_CPU_INTEL_PM
Intel Pentium M CPU。

サポートされる PMC

このライブラリによってサポートされる PMC は、 enum pmc_class 列挙型によって指定されます。サポートされる PMC の種類は、次の通りです:

PMC_CLASS_IAF
Intel 性能測定アーキテクチャのバージョン 2 以降に準拠している CPU に存在する固定関数ハードウェアカウンタ。
PMC_CLASS_IAP
Intel 性能測定アーキテクチャのバージョン 1 以降に準拠している CPU に存在するプログラマブルカウンタ。
PMC_CLASS_K7
AMD Athlon CPU に存在しているプログラマブルハードウェアカウンタ。
PMC_CLASS_K8
AMD Athlon64 CPU に存在しているプログラマブルハードウェアカウンタ。
PMC_CLASS_P4
Intel Pentium 4 CPU に存在しているプログラマブルハードウェアカウンタ。
PMC_CLASS_P5
Intel Pentium CPU に存在しているプログラマブルハードウェアカウンタ。
PMC_CLASS_P6
Intel Pentium Pro, Pentium II, Pentium III, Celeron と Pentium M CPU に存在しているプログラマブルハードウェアカウンタ。
PMC_CLASS_TSC
i386 と amd64 アーキテクチャのタイムスタンプカウンタ。
PMC_CLASS_SOFT
ソフトウェアイベント。

PMC ケーパビリティ (能力)

性能モニタリングハードウェアのケーパビリティは、 enum pmc_caps 列挙型を使用して示されます。サポートされたケーパビリティは、次の通りです:

PMC_CAP_CASCADE
カスケードカウンタ能力。
PMC_CAP_EDGE
カウントされる能力は、プローブされるハードウェア条件のアサートされた遷移に否定されました。
PMC_CAP_INTERRUPT
CPU を割り込む能力。
PMC_CAP_INVERT
測定されるハードウェア条件の意味を逆にする能力。
PMC_CAP_PRECISE
正確なサンプリングを実行する能力。
PMC_CAP_QUALIFIER
ハードウェアによって、モニタは、システムに依存する何らかの方法でさらに修飾することができます。
PMC_CAP_READ
性能カウンタから読み込む能力。
PMC_CAP_SYSTEM
CPU が特権があるコードで実行されているとき、ハードウェアイベントのカウントを制限する能力。
PMC_CAP_THRESHOLD
プログラマブルな閾値より下で同時に起こるハードウェアイベントを無視する能力。
PMC_CAP_USER
CPU が非特権コードで実行されているとき、それらへのハードウェアイベントのカウントを制限する能力。
PMC_CAP_WRITE
性能カウンタを書き込む能力。

CPU 命名規則 (CPU Naming Conventions)

CPU は、関数 pmc_ncpu() によって返された値を除いて、0 以上の小さな整数を使用して命名されます。まばらに番号付けされた CPU をサポートするプラットフォームでは、この範囲のすべての数値とは限らなくて、有効な CPU を指示します。存在しない CPU における操作は、エラーを返します。

API の機能的なグループ分け

このセクションは、PMC ライブラリで利用可能な機能性の簡潔な概要を含んでいます。ここにリストされた各関数は、それ自体のマニュアルページで、より詳しく説明されています。
管理
pmc_disable(), pmc_enable()
特定の性能モニタリングカウンタのハードウェアを管理上無効に (有効に) します。無効にされたカウンタは、使用するアプリケーションで利用可能になりません。
便利な関数
pmc_event_names_of_class()
与えられた PMC タイプでサポートされたイベント名のリストを返します。
pmc_name_of_capability()
PMC_CAP_* フラグを人間に読み込み可能な文字列に変換します。
pmc_name_of_class()
PMC_CLASS_* 定数を人間に読み込み可能な文字列に変換します。
pmc_name_of_cputype()
CPU タイプの人間に読み込み可能な名前を返します。
pmc_name_of_disposition()
PMC の性質について説明する人間に読み込み可能な文字列を返します。
pmc_name_of_event()
数値のイベントコードを人間に読み込み可能な文字列に変換します。
pmc_name_of_mode()
PMC_MODE_* 定数を人間に読み込み可能な名前に変換します。
pmc_name_of_state()
PMC の現在の状態を説明する人間に読み込み可能な文字列を返します。
ライブラリの初期化
pmc_init()
ライブラリを初期化します。この関数は、いかなる他のライブラリ関数の前に呼び出されなければなりません。
ログファイルの操作
pmc_configure_logfile()
ログ記録されたイベントを書き込むために hwpmc(4) のためのログファイルを設定します。
pmc_flush_logfile()
hwpmc(4) バッファのすべての保留中 (pending) のログデータをフラッシュします。
pmc_close_logfile()
すべての保留中のログデータをフラッシュし、ストリームの hwpmc(4) 側をクローズします。
pmc_writelog()
任意のユーザデータを現在のログファイルに追加します。
PMC 管理
pmc_allocate(), pmc_release()
PMC を割り付けます (解放します)。
pmc_attach(), pmc_detach()
プロセススコープ PMC をターゲットにアタッチします (デタッチします)。
pmc_read(), pmc_write(), pmc_rw()
PMC から (へ) 値を読み込みます (書き込みます)。
pmc_start(), pmc_stop()
ソフトウェア PMC を開始します (停止します)。
pmc_set()
サンプリング PMC のための再ロード値を設定します。
問い合わせ
pmc_capabilities()
与えられた PMC のケーパビリティを検索します。
pmc_cpuinfo()
システムの現在の CPU と PMC ハードウェアに関する情報を検索します。
pmc_get_driver_stats()
hwpmc(4) によって維持された統計を検索します。
pmc_ncpu()
システムの可能な限り最大の CPU の数を測定します。
pmc_npmc()
与えられた CPU に存在するハードウェア PMC の数を返します。
pmc_pmcinfo()
与えられた CPU の PMC の状態に関する情報を返します。
pmc_width()
ビット単位でハードウェアカウンタの幅を測定します。
x86 アーキテクチャ特有の API
pmc_get_msr()
pmc に関連しているプロセッサモデル特有のレジスタ番号を返します。次に、アプリケーションは、直接 PMC の内容を読み込むために x86 RDPMC 命令を使用します。

シグナル操作要件

PMC を使用するアプリケーションは、次のシグナルを取り扱うために必要とされます:
SIGBUS
hwpmc(4) モジュールが kldunload(8) を使用してアンロードされるとき、それらに割り付けられた PMC があるプロセスは、 SIGBUS シグナルが送られます。
SIGIO
hwpmc(4) ドライバは、次の場合、 SIGIO シグナルを PMC を所有のプロセスに送ります:
  • それによって割り付けられた任意のプロセスモード PMC が、すべてのターゲットプロセスを失う場合、
  • 設定されたログファイルにログデータを書き込むとき、ドライバがエラーに遭遇した場合、このエラーは、 pmc_flush_logfile() へのその後の呼び出しで検索されるかもしれません。

典型的なプログラムフロー

  1. アプリケーションは、最初に、ライブラリがそれ自体を初期化することができる、関数 pmc_init() を呼び出します。
  2. 次に、シグナルの取り扱いがセットアップされます。
  3. 次に、アプリケーションは、要求される関数 pmc_allocate() を使用して PMC を割り付けます。
  4. PMC のための初期の値は、関数 pmc_set() を使用して設定されます。
  5. ログファイルが PMC が動作するために必要であるなら、関数 pmc_configure_logfile() を使用して設定されます。
  6. 次に、プロセススコープ PMC は、関数 pmc_attach() を使用してそれらのターゲットのプロセスにアタッチされます。
  7. 次に、PMC は、関数 pmc_start() を使用して開始されます。
  8. いったん開始されると、PMC をカウントする値は、関数 pmc_read() を使用して読み込まれます。ログファイルにイベントを書き込む PMC に関して、このログ記録されたデータは、 pmclog(3) 関数ファミリを使用して読み込まれ、解析されます。
  9. PMC は、関数 pmc_stop() を使用して停止され、プロセススコープ PMC は、それらのターゲットから関数 pmc_detach() を使用してデタッチされます。
  10. プロセスが終了する前に、関数 pmc_release() を使用して PMC を解放します。任意の設定されたログファイルは、関数 pmc_configure_logfile() を使用してクローズされます。

イベント指定子

イベント指定子は、プローブされるハードウェアイベントのセマンティックを変更するオプションのパラメータがあとに続いた、イベント名が含まれる文字列です。イベント名は、PMC アーキテクチャに依存していますが、 PMC ライブラリは、共通に使用されたイベントのためのマシンの独立している別名を定義します。

イベント指示子のスペルは、大文字と小文字を区別せず、空白文字、ピリオド、下線とハイフンは、互いに同等であるみなされます。したがって、イベント記述子“Example Event”, “example-event”と“EXAMPLE_EVENT”は、同等です。

PMC アーキテクチャ依存のイベント。

PMC アーキテクチャに依存するイベント指示子は、次のマニュアルページに説明されています:
PMC Class Manual Page
PMC_CLASS_IAF pmc.iaf(3)
PMC_CLASS_IAP pmc.atom(3), pmc.core(3), pmc.core2(3)
PMC_CLASS_K7 pmc.k7(3)
PMC_CLASS_K8 pmc.k8(3)
PMC_CLASS_P4 pmc.p4(3)
PMC_CLASS_P5 pmc.p5(3)
PMC_CLASS_P6 pmc.p6(3)
PMC_CLASS_TSC pmc.tsc(3)

イベント名の別名

イベント名の別名は、共通に使用されたイベントのための PMC に独立している名前です。次の別名が、 pmc ライブラリのこのバージョンで知られています:
branches
リタイアした分岐の数を測定します。
branch-mispredicts
予測ミスされたリタイアした分岐の数を測定します。
cycles
プロセッササイクルを測定します。このイベントは、プロセッサの Time Stamp Counter レジスタを使用して実装されています。
dc-misses
データキャッシュミスの数を測定します。
ic-misses
命令キャッシュミスの数を測定します。
instructions
リタイアした命令の数を測定します。
interrupts
調べられた割り込みの数を測定します。
unhalted-cycles
停止したか、またはスリープ状態でないプロセッサのサイクルの数を測定します。

互換性

pmc ライブラリと hwpmc(4) ドライバとの間のインタフェースは、実装のためにプライベートにされることを目的としていて、変更するかもしれません。 hwpmc(4) ドライバの将来のバージョンとの前方互換を簡単にするために、アプリケーションは、 pmc ライブラリで動的にリンクするように強く勧められます。

pmc API は、現在、開発中です。

歴史

pmc ライブラリは、 FreeBSD 6.0 ではじめて登場しました。

作者

Performance Counters Library (libpmc, -lpmc) ライブラリは、 Joseph Koshy <jkoshy@FreeBSD.org>によって書かれました。
November 24, 2008 FreeBSD