Linuxでperf_events
を使用して監視できるwhatを検索していますが、Kernel PMU event
が何であるかわかりませんか?つまり、perf version 3.13.11-ckt39
を使用すると、perf list
は次のようなイベントを表示します。
branch-instructions OR cpu/branch-instructions/ [Kernel PMU event]
全体的には次のとおりです。
Tracepoint event
Software event
Hardware event
Hardware cache event
Raw hardware event descriptor
Hardware breakpoint
Kernel PMU event
そして、私は彼らが何であるか、彼らがどこから来たかを理解したいと思います。なんらかの説明がありますが、Kernel PMU event
アイテムです。
perf wiki tutorial および Brendan Gregg's page から:
Tracepoints
は最も明確です。これらはカーネルソース上のマクロであり、監視のためのプローブポイントを作成します。これらはftrace
プロジェクトで導入され、現在すべての人が使用していますSoftware
はカーネルの低レベルのカウンターといくつかの内部データ構造です(したがって、これらはトレースポイントとは異なります)Hardware event
は、allアーキテクチャで見つかり、何らかの方法でカーネルから簡単にアクセスできる、非常に基本的なCPUイベントですHardware cache event
はRaw hardware event descriptor
のニックネームです-次のように機能します
私が得たように、Raw hardware event descriptor
はHardware event
よりも(マイクロ?)アーキテクチャ固有のイベントであり、イベントはプロセッサモニタリングユニット(PMU)または特定のプロセッサの他の特定の機能からのものであるため、利用可能です一部のマイクロアーキテクチャーのみ(「アーキテクチャー」は「x86_64」を意味し、残りの実装詳細はすべて「マイクロアーキテクチャー」であるとします);これらは、これらの奇妙な記述子を介してインストルメンテーションにアクセスできます
rNNN [Raw hardware event descriptor]
cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor]
(see 'man perf-list' on how to encode it)
-これらの記述子、それらが指すイベントなどは、プロセッサのマニュアルに記載されています( perf wikiのPMUイベント );
しかし、人々が特定のプロセッサにいくつかの有用なイベントがあることを知ったとき、彼らはそれにニックネームを付け、アクセスを容易にするためにHardware cache event
としてLinuxにプラグインします。
-私が間違っている場合は修正してください(奇妙なことに、すべてのHardware cache event
はsomething-loads
またはsomething-misses
についてです-実際のプロセッサのキャッシュと非常によく似ています。)
今、Hardware breakpoint
mem:<addr>[:access] [Hardware breakpoint]
ハードウェア機能は、おそらく最新のアーキテクチャーに一般的であり、デバッガーのブレークポイントとして機能しますか? (とにかくそれはグーグル可能です)
最後に、Kernel PMU event
グーグルで管理できません。
ブレンダンのパフォーマンスページのイベントのリスト にも表示されないので、新しいですか?
多分それは特にPMUからのハードウェアイベントへのニックネームだけですか? (アクセスを簡単にするために、ニックネームに加えて、イベントのリストに別のセクションがあります。)実際、Hardware cache events
はCPUのキャッシュからのハードウェアイベントのニックネームであり、Kernel PMU event
はPMUイベントのニックネームです? (なぜそれをHardware PMU event
と呼ばないのですか?..)それは単なる新しい命名方式である可能性があります-ハードウェアイベントのニックネームはセクション化されましたか?
そして、これらのイベントはcpu/mem-stores/
のようなものを参照します。さらに、一部のLinuxバージョンのイベントは/sys/devices/
で説明されているため、
# find /sys/ -type d -name events
/sys/devices/cpu/events
/sys/devices/uncore_cbox_0/events
/sys/devices/uncore_cbox_1/events
/sys/kernel/debug/tracing/events
-debug/tracing
はftrace
およびトレースポイント用で、他のディレクトリはperf list
がKernel PMU event
として表示するものと完全に一致します。
誰かが私にKernel PMU events
または/sys/..events/
システムが何であるかについての適切な説明/ドキュメントを教えてもらえますか?また、/sys/..events/
は、ハードウェアイベントなどをシステム化するための新しい取り組みですか? (つまり、カーネルPMUは「カーネルのパフォーマンス監視ユニット」のようなものです。)
より良いコンテキストを与えるために、perf list
の非特権実行(トレースポイントは表示されていませんが、それらの1374はすべてあります)で、Kernel PMU event
sとHardware cache event
sの完全なリストとその他をスキップします:
$ perf list
List of pre-defined events (to be used in -e):
cpu-cycles OR cycles [Hardware event]
instructions [Hardware event]
...
cpu-clock [Software event]
task-clock [Software event]
...
L1-dcache-load-misses [Hardware cache event]
L1-dcache-store-misses [Hardware cache event]
L1-dcache-prefetch-misses [Hardware cache event]
L1-icache-load-misses [Hardware cache event]
LLC-loads [Hardware cache event]
LLC-stores [Hardware cache event]
LLC-prefetches [Hardware cache event]
dTLB-load-misses [Hardware cache event]
dTLB-store-misses [Hardware cache event]
iTLB-loads [Hardware cache event]
iTLB-load-misses [Hardware cache event]
branch-loads [Hardware cache event]
branch-load-misses [Hardware cache event]
branch-instructions OR cpu/branch-instructions/ [Kernel PMU event]
branch-misses OR cpu/branch-misses/ [Kernel PMU event]
bus-cycles OR cpu/bus-cycles/ [Kernel PMU event]
cache-misses OR cpu/cache-misses/ [Kernel PMU event]
cache-references OR cpu/cache-references/ [Kernel PMU event]
cpu-cycles OR cpu/cpu-cycles/ [Kernel PMU event]
instructions OR cpu/instructions/ [Kernel PMU event]
mem-loads OR cpu/mem-loads/ [Kernel PMU event]
mem-stores OR cpu/mem-stores/ [Kernel PMU event]
ref-cycles OR cpu/ref-cycles/ [Kernel PMU event]
stalled-cycles-frontend OR cpu/stalled-cycles-frontend/ [Kernel PMU event]
uncore_cbox_0/clockticks/ [Kernel PMU event]
uncore_cbox_1/clockticks/ [Kernel PMU event]
rNNN [Raw hardware event descriptor]
cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor]
(see 'man perf-list' on how to encode it)
mem:<addr>[:access] [Hardware breakpoint]
[ Tracepoints not available: Permission denied ]
グーグルとack
- ingは終了しました!いくつか答えがあります。
ただし、最初に、質問の目的をもう少し明確にしましょう。システム内の独立したプロセスとそのパフォーマンスカウンターを明確に区別したいのです。たとえば、プロセッサのコア、アンコアデバイス(最近それについて学習)、プロセッサのカーネルまたはユーザーアプリケーション、バス(=バスコントローラ)、ハードドライブはすべて独立したプロセスであり、クロックによって同期されません。そして今日ではおそらくそれらすべてに何らかのプロセス監視カウンター(PMC)があります。カウンターがどのプロセスからのものかを理解したいと思います。 (これはグーグルにも役立ちます。物事の「ベンダー」はそれをよりよくゼロにします。)
また、検索に使用されるギア:_Ubuntu 14.04
_、_linux 3.13.0-103-generic
_、プロセッサーIntel(R) Core(TM) i5-3317U CPU @ 1.70GHz
(_/proc/cpuinfo
_から、2つの物理コアと4つの仮想-ここでは物理的な問題)。
インテルから:
プロセッサはcore
デバイス(それは1つのデバイス/プロセスです)とuncore
デバイスの束 、core
はプログラムを実行するものです(クロック、 ALU、レジスタなど)、uncore
はダイに配置されたデバイスであり、プロセッサの近くで速度と低遅延を実現します(本当の理由は、「製造者ができるため」です)。私が理解したように、それは基本的にPCマザーボードのようなノースブリッジとキャッシュです。 AMDは実際にこれらのデバイスをNorthBridge _instead of
_ uncore`と呼びます。
ubox
は私のsysfs
に表示されます
_$ find /sys/devices/ -type d -name events
/sys/devices/cpu/events
/sys/devices/uncore_cbox_0/events
/sys/devices/uncore_cbox_1/events
_
-最後のレベルのキャッシュ(LLC、RAMにアクセスする前の最後のキャッシュ)を管理するuncore
デバイスです。私は2つのコア、つまり2つのLLCと2つのubox
を持っています。
プロセッサ監視ユニット(PMU)は、プロセッサの動作を監視し、それらをプロセッサ監視カウンタ(PMC)に記録する個別のデバイスです(キャッシュミス、プロセッササイクルなどをカウントします)。それらはcore
およびuncore
デバイスに存在します。 core
のものはrdpmc
(PMCの読み取り)命令でアクセスされます。これらのデバイスは実際のプロセッサに依存しているため、uncore
にはrdmsr
を介してモデル固有レジスター(MSR)を介してアクセスします(当然)。
明らかに、それらのワークフローは、レジスタのペアを介して行われます。1つのレジスタは、カウンタがカウントするイベントを設定します。2つのレジスタは、カウンタの値です。カウンタは、1つだけでなく、一連のイベントの後に増分するように構成できます。 +これらのカウンターのオーバーフローに気づくいくつかの中断/技術があります。
intelの「IA-32ソフトウェア開発者向けマニュアルVol 3B」の第18章「パフォーマンスモニタリング」でさらに多くの情報を見つけることができます。
また、これらのuncore
PMCのバージョン「Architectural Performance Monitoring Version 1」のMSRの形式(マニュアルにはバージョン1〜4があり、どちらが私のプロセッサかわかりません)については、「図18-1。IA32_PERFEVTSELx MSRのレイアウト」(18-3ページ)、および「表18-1。定義済みのアーキテクチャパフォーマンス用のUMaskおよびイベント選択エンコーディング」のセクション「18.2.1.2定義済みのアーキテクチャパフォーマンスイベント」イベント」は、_Hardware event
_で_perf list
_として表示されるイベントを示します。
Linuxカーネルから:
カーネルには、ソフトウェア(カーネル)とハードウェアの両方の異なるOriginのパフォーマンスカウンターを管理するためのシステム(抽象化/レイヤー)があり、_linux-source-3.13.0/tools/perf/design.txt
_で説明されています。このシステムのイベントは_struct perf_event_attr
_(ファイル_linux-source-3.13.0/include/uapi/linux/perf_event.h
_)として定義され、その主要部分はおそらく___u64 config
_フィールドです-CPU固有のイベント定義(64ビットそれらのIntelの図に記載されている形式の単語)またはカーネルのイベント
構成ワードのMSBは、残りに[生のCPUまたはカーネルのイベント]が含まれているかどうかを示します
タイプの7ビットとイベントの識別子の56で定義されたカーネルのイベント。これはコードではenum
- sであり、私の場合は次のとおりです。
_$ ak PERF_TYPE linux-source-3.13.0/include/
...
linux-source-3.13.0/include/uapi/linux/perf_event.h
29: PERF_TYPE_HARDWARE = 0,
30: PERF_TYPE_SOFTWARE = 1,
31: PERF_TYPE_TRACEPOINT = 2,
32: PERF_TYPE_HW_CACHE = 3,
33: PERF_TYPE_RAW = 4,
34: PERF_TYPE_BREAKPOINT = 5,
36: PERF_TYPE_MAX, /* non-ABI */
_
(ak
は、Debianでのack
の名前である_ack-grep
_の私のエイリアスです。ack
は素晴らしいです);
カーネルのソースコードでは、「システムで検出されたすべてのPMUを登録する」などの操作と、int perf_pmu_register(struct pmu *pmu, const char *name, int type)
などに渡される構造タイプ_struct pmu
_を確認できます。システム「カーネルのPMU」。これは、システム上のすべてのPMUの集約です。しかし、この名前はカーネルの操作の監視システムとして解釈され、誤解を招く可能性があります。
わかりやすくするために、このサブシステムを_perf_events
_と呼びましょう。
他のカーネルサブシステムと同様に、このサブシステムはsysfs
にエクスポートできます(これは、使用するカーネルサブシステムをエクスポートするために作成されます)。そして、それが私の_/sys/
_にあるevents
ディレクトリです-エクスポートされた(一部?)_perf_events
_サブシステム;
また、ユーザー空間ユーティリティperf
(linuxに組み込まれている)は、まだ別のプログラムであり、独自の抽象化を持っています。これは、ユーザーによる監視が要求されたイベントを_perf_evsel
_(ファイル_linux-source-3.13.0/tools/perf/util/evsel.{h,c}
_)として表します-この構造にはフィールド_struct perf_event_attr attr;
_がありますが、_struct cpu_map *cpus;
_のようなフィールドもありperf
ユーティリティは、すべてまたは特定のCPUにイベントを割り当てます。
実際、_Hardware cache event
_は、キャッシュデバイス(インテルのubox
デバイスのuncore
)のイベントへの「ショートカット」であり、プロセッサ固有であり、プロトコルを介してアクセスできます_Raw hardware event descriptor
_。そして、_Hardware event
_はアーキテクチャ内でより安定しており、私が理解しているように、core
デバイスからのイベントに名前を付けています。私のカーネルには、他のuncore
イベントおよびカウンターへの_3.13
_の他の「ショートカット」はありません。残りのすべて(Software
およびTracepoints
)は、カーネルのイベントです。
core
の_Hardware event
_ sは、同じ_Raw hardware event descriptor
_プロトコルを介してアクセスされるのでしょうか。そうではないかもしれません-カウンター/ PMUはcore
にあるため、おそらく異なる方法でアクセスされます。たとえば、rdpmu
にアクセスするrdmsr
の代わりに、そのuncore
命令を使用します。しかし、それはそれほど重要ではありません。
_Kernel PMU event
_はsysfs
にエクスポートされる単なるイベントです。これがどのように行われるかはわかりません(システムによって検出されたすべてのPMCをカーネルが自動的に、またはハードコードされたものだけで、kprobe
を追加すると-エクスポートされますか?など)。ただし、重要な点は、これらは_Hardware event
_または内部_perf_event
_システムの他のイベントと同じイベントであることです。
そして、私はそれらのことを知りません
_$ ls /sys/devices/uncore_cbox_0/events
clockticks
_
あります。
Kernel PMU event
_の詳細コードを検索すると、次のようになります。
_$ ak "Kernel PMU" linux-source-3.13.0/tools/perf/
linux-source-3.13.0/tools/perf/util/pmu.c
629: printf(" %-50s [Kernel PMU event]\n", aliases[j]);
_
-関数で発生します
_void print_pmu_events(const char *event_glob, bool name_only) {
...
while ((pmu = perf_pmu__scan(pmu)) != NULL)
list_for_each_entry(alias, &pmu->aliases, list) {...}
...
/* b.t.w. list_for_each_entry is an iterator
* apparently, it takes a block of {code} and runs over some lost
* Ruby built in kernel!
*/
// then there is a loop over these aliases and
loop{ ... printf(" %-50s [Kernel PMU event]\n", aliases[j]); ... }
}
_
および_perf_pmu__scan
_は同じファイルにあります:
_struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) {
...
pmu_read_sysfs(); // that's what it calls
}
_
-これも同じファイルにあります:
_/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void) {...}
_
それでおしまい。
Hardware event
_および_Hardware cache event
_の詳細どうやら、_Hardware event
_は、IAがIA-32ソフトウェア開発者向けマニュアルVol 3Bの18.2.1.2である「定義済みのアーキテクチャパフォーマンスイベント」と呼んでいるものに由来します。また、マニュアルの「18.1パフォーマンスモニタリングの概要」では、次のように説明しています。
2番目のクラスのパフォーマンス監視機能は、アーキテクチャパフォーマンス監視と呼ばれます。このクラスは、同じカウントと割り込みベースのイベントサンプリングの使用法をサポートします。使用可能なイベントのセットは少なくなります。アーキテクチャパフォーマンスイベントの目に見える動作は、プロセッサの実装全体で一貫しています。アーキテクチャパフォーマンス監視機能の可用性は、CPUID.0AHを使用して列挙されます。これらのイベントについては、セクション18.2で説明します。
-他のタイプは次のとおりです:
Intel Core SoloおよびIntel Core Duoプロセッサ以降、パフォーマンス監視機能には2つのクラスがあります。最初のクラスは、カウントまたは割り込みベースのイベントサンプリングの使用を使用してパフォーマンスを監視するイベントをサポートします。これらのイベントは非アーキテクチャであり、プロセッサモデルによって異なります...
そして、これらのイベントは実際には、基礎となる「生の」ハードウェアイベントへのリンクにすぎず、perf
ユーティリティを介して_Raw hardware event descriptor
_としてアクセスできます。
これを確認するには、_linux-source-3.13.0/Arch/x86/kernel/cpu/perf_event_intel.c
_を見てください。
_/*
* Intel PerfMon, used on Core and later.
*/
static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
{
[PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
[PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
...
}
_
-そして正確に_0x412e
_は、「LLCミス」の「表18-1。事前定義されたアーキテクチャパフォーマンスイベントのUMaskおよびイベント選択エンコーディング」にあります。
_Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
4 | LLC Misses | 41H | 2EH
_
-H
は16進数です。 7つすべてが構造内にあり、さらに_[PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *
_も含まれています。 (名前は少し異なり、アドレスは同じです。)
次に、_Hardware cache event
_ sは(同じファイル内)のような構造になります。
_static __initconst const u64 snb_hw_cache_extra_regs
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
{...}
_
-砂の橋にはどちらを使うべきですか?
これらのうちの1つ-_snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]
_は_SNB_DMND_WRITE|SNB_L3_ACCESS
_で埋められ、上記のdef-sから:
_#define SNB_L3_ACCESS SNB_RESP_ANY
#define SNB_RESP_ANY (1ULL << 16)
#define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO)
#define SNB_DMND_RFO (1ULL << 1)
#define SNB_LLC_RFO (1ULL << 8)
_
これは_0x00010102
_に等しいはずですが、テーブルで確認する方法がわかりません。
そして、これは_perf_events
_でどのように使用されるかを示します:
_$ ak hw_cache_extra_regs linux-source-3.13.0/Arch/x86/kernel/cpu/
linux-source-3.13.0/Arch/x86/kernel/cpu/perf_event.c
50:u64 __read_mostly hw_cache_extra_regs
292: attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
linux-source-3.13.0/Arch/x86/kernel/cpu/perf_event.h
521:extern u64 __read_mostly hw_cache_extra_regs
linux-source-3.13.0/Arch/x86/kernel/cpu/perf_event_intel.c
272:static __initconst const u64 snb_hw_cache_extra_regs
567:static __initconst const u64 nehalem_hw_cache_extra_regs
915:static __initconst const u64 slm_hw_cache_extra_regs
2364: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2365: sizeof(hw_cache_extra_regs));
2407: memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
2408: sizeof(hw_cache_extra_regs));
2424: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2425: sizeof(hw_cache_extra_regs));
2452: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2453: sizeof(hw_cache_extra_regs));
2483: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2484: sizeof(hw_cache_extra_regs));
2516: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
$
_
memcpy
sは__init int intel_pmu_init(void) {... case:...}
で行われます。
_attr->config1
_だけが少し奇妙です。しかし、それは_perf_event_attr
_(同じ_linux-source-3.13.0/include/uapi/linux/perf_event.h
_ファイル)にあります。
_...
union {
__u64 bp_addr;
__u64 config1; /* extension of config */
};
union {
__u64 bp_len;
__u64 config2; /* extension of config1 */
};
...
_
これらはカーネルの_perf_events
_システムに登録され、int perf_pmu_register(struct pmu *pmu, const char *name, int type)
を呼び出します(_linux-source-3.13.0/kernel/events/core.c:
_で定義):
static int __init init_hw_perf_events(void)
(ファイル_Arch/x86/kernel/cpu/perf_event.c
_)呼び出しperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
(ファイル_Arch/x86/kernel/cpu/perf_event_intel_uncore.c
_、_Arch/x86/kernel/cpu/perf_event_AMD_uncore.c
_もあります)ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
を呼び出します
つまり、すべてのイベントはハードウェアからのものであり、すべて問題ありません。しかし、ここで気づくでしょう:なぜ_LLC-loads
_ではなく_perf list
_に_ubox1 LLC-loads
_があるのですか?これらはHWイベントであり、実際にはubox
esから来ているのですか?
これはperf
ユーティリティとその_perf_evsel
_構造の問題です。perf
からHWイベントを要求すると、どのプロセッサーからイベントを取得するかを定義します(デフォルトはすべて) 、および要求されたイベントとプロセッサで_perf_evsel
_を設定します。その後、集計では_perf_evsel
_内のすべてのプロセッサからのカウンタが合計されます(またはそれらと他の統計が行われます)。
_tools/perf/builtin-stat.c
_で確認できます。
_/*
* Read out the results of a single counter:
* aggregate counts across CPUs in system-wide mode
*/
static int read_counter_aggr(struct perf_evsel *counter)
{
struct perf_stat *ps = counter->priv;
u64 *count = counter->counts->aggr.values;
int i;
if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
thread_map__nr(evsel_list->threads), scale) < 0)
return -1;
for (i = 0; i < 3; i++)
update_stats(&ps->res_stats[i], count[i]);
if (verbose) {
fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
perf_evsel__name(counter), count[0], count[1], count[2]);
}
/*
* Save the full runtime - to allow normalization during printout:
*/
update_shadow_stats(counter, count);
return 0;
}
_
(つまり、ユーティリティperf
の場合、「単一のカウンター」は_perf_event_attr
_でもありません。これはSWとHWの両方のイベントに当てはまる一般的な形式であり、クエリのイベントです-同じイベントが異なるデバイスから発生する可能性があり、それらは集約されます。)
また、注意事項:_struct perf_evsel
_には1つの_struct perf_evevent_attr
_のみが含まれますが、フィールド_struct perf_evsel *leader;
_も含まれています-ネストされています。 _perf_events
_には、「(階層的)グループのイベント」という機能があり、多数のカウンターをまとめてディスパッチして、それらを互いに比較できるようにしています。 kernel
、core
、ubox
からの独立したイベントでどのように機能するかわかりません。しかし、この_perf_evsel
_の入れ子はそれだけです。そしておそらく、それがperf
が複数のイベントのクエリを一緒に管理する方法です。