Googling dan ack
-ing sudah berakhir! Saya punya jawaban.
Tetapi pertama-tama izinkan saya mengklarifikasi tujuan dari pertanyaan ini sedikit lagi: Saya ingin membedakan proses independen dalam sistem dan penghitung kinerjanya. Misalnya, inti dari sebuah prosesor, perangkat yang tidak dihapus (dipelajari baru-baru ini), kernel atau aplikasi pengguna pada prosesor, bus (= bus controller), hard drive adalah semua proses independen, mereka tidak disinkronkan oleh jam . Dan saat ini mungkin mereka semua memiliki Pemantauan Proses Counter (PMC). Saya ingin memahami dari mana proses penghitung itu berasal. (Ini juga membantu dalam googling: "vendor" dari suatu hal nol lebih baik.)
Juga, roda gigi yang digunakan untuk pencarian: Ubuntu 14.04
,, linux 3.13.0-103-generic
prosesor Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
(dari /proc/cpuinfo
, ia memiliki 2 inti fisik dan 4 virtual - masalah fisik di sini).
Terminologi, hal-hal yang melibatkan pertanyaan
Dari Intel:
Prosesor adalah core
perangkat (ini adalah 1 perangkat / proses) dan banyak uncore
perangkat , core
adalah apa yang menjalankan program (jam, ALU, register dll), uncore
adalah perangkat yang diletakkan di tempat, dekat dengan prosesor untuk kecepatan dan latensi rendah (alasan sebenarnya adalah "karena pabrikan dapat melakukannya"); seperti yang saya mengerti pada dasarnya adalah Northbridge, seperti pada motherboard PC, ditambah cache; dan AMD benar-benar menyebut perangkat ini NorthBridge instead of
uncore`;
ubox
yang muncul di blog saya sysfs
$ find /sys/devices/ -type d -name events
/sys/devices/cpu/events
/sys/devices/uncore_cbox_0/events
/sys/devices/uncore_cbox_1/events
- adalah uncore
perangkat, yang mengelola Last Level Cache (LLC, yang terakhir sebelum menekan RAM); Saya memiliki 2 core, dengan demikian 2 LLC dan 2 ubox
;
Unit Pemantau Prosesor (PMU) adalah perangkat terpisah yang memantau operasi prosesor dan mencatatnya dalam Penghitung Pemantauan Prosesor (PMC) (menghitung kesalahan cache, siklus prosesor, dll); mereka ada di core
dan uncore
perangkat; yang core
yang diakses dengan rdpmc
(baca PMC) instruksi; yang uncore
, karena perangkat ini tergantung pada prosesor yang sebenarnya di tangan, yang diakses melalui Register Specific Model (MSR) melalui rdmsr
(secara alami);
rupanya, alur kerja dengan mereka dilakukan melalui pasangan register - 1 set register yang peristiwa penghitungan dihitung, 2 register adalah nilai di penghitung; penghitung dapat dikonfigurasikan ke kenaikan setelah banyak acara, bukan hanya 1; + ada beberapa interupts / tech memperhatikan overflow di penghitung ini;
lebih banyak yang dapat ditemukan di "Panduan Pengembang Perangkat Lunak IA-32 Intel Vol 3B" bab 18 "PEMANTAUAN KINERJA";
juga, format MSR secara konkret untuk uncore
PMC ini untuk versi "Arsitektur Pemantauan Kinerja Versi 1" (ada versi 1-4 dalam manual, saya tidak tahu yang mana prosesor saya) dijelaskan dalam "Gambar 18-1. Tata Letak IA32_PERFEVTSELx MSRs "(halaman 18-3 di tambang), dan bagian" 18.2.1.2 Acara Kinerja Arsitektur Pra-terdefinisi "dengan" Tabel 18-1. UMask dan Enkode Pemilihan Acara untuk Acara Performa Arsitektur Pra-Defined ", yang menunjukkan acara yang muncul seperti Hardware event
pada perf list
.
Dari kernel linux:
kernel memiliki sistem (abstraksi / layer) untuk mengelola penghitung kinerja dari asal yang berbeda, baik perangkat lunak (kernel) dan perangkat keras, dijelaskan dalam linux-source-3.13.0/tools/perf/design.txt
; suatu kejadian dalam sistem ini didefinisikan sebagai struct perf_event_attr
(file linux-source-3.13.0/include/uapi/linux/perf_event.h
), bagian utama yang kemungkinan adalah __u64 config
bidang - ia dapat menampung definisi peristiwa khusus-CPU (kata 64bit dalam format yang dijelaskan pada angka-angka Intel) atau acara kernel
MSB kata konfigurasi menandakan jika sisanya berisi [CPU mentah atau acara kernel]
acara kernel didefinisikan dengan 7 bit untuk tipe dan 56 untuk pengidentifikasi acara, yang enum
-s dalam kode, yang dalam kasus saya adalah:
$ 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
adalah alias saya untuk ack-grep
, yang merupakan nama untuk ack
di Debian; dan ack
mengagumkan);
dalam kode sumber kernel kita dapat melihat operasi seperti "daftarkan semua PMU yang ditemukan pada sistem" dan tipe struktur struct pmu
, yang diteruskan ke sesuatu seperti int perf_pmu_register(struct pmu *pmu, const char *name, int type)
- dengan demikian, kita dapat memanggil sistem ini "PMU kernel", yang akan menjadi agregasi dari semua PMU pada sistem; tetapi nama ini dapat diartikan sebagai sistem pemantauan operasi kernel, yang akan menyesatkan;
mari kita sebut subsistem ini perf_events
untuk kejelasan;
sebagai subsistem kernel apa pun, subsistem ini dapat diekspor ke sysfs
(yang dibuat untuk mengekspor subsistem kernel untuk digunakan orang); dan itulah events
direktori - direktori di dalam saya /sys/
- perf_events
subsistem (bagian dari?) yang diekspor ;
juga, utilitas ruang pengguna perf
(dibangun di linux) masih merupakan program yang terpisah dan memiliki abstraksi sendiri; itu mewakili suatu peristiwa yang diminta untuk pemantauan oleh pengguna sebagai perf_evsel
(file linux-source-3.13.0/tools/perf/util/evsel.{h,c}
) - struktur ini memiliki bidang struct perf_event_attr attr;
, tetapi juga bidang seperti struct cpu_map *cpus;
itulah cara perf
utilitas menetapkan suatu peristiwa untuk semua atau CPU tertentu.
Menjawab
Memang, Hardware cache event
"jalan pintas" ke peristiwa perangkat cache (perangkat ubox
Intel uncore
), yang khusus untuk prosesor, dan dapat diakses melalui protokol Raw hardware event descriptor
. Dan Hardware event
lebih stabil dalam arsitektur, yang, seperti yang saya mengerti, menamai peristiwa dari core
perangkat. Tidak ada "pintasan" lainnya di kernel saya 3.13
ke beberapa uncore
acara dan penghitung lainnya. Semua yang lainnya - Software
dan Tracepoints
- adalah acara kernel.
Aku ingin tahu apakah core
's Hardware event
s diakses melalui sama Raw hardware event descriptor
protokol. Mereka mungkin tidak - karena penghitung / PMU duduk core
, mungkin itu diakses secara berbeda. Misalnya, dengan rdpmu
instruksi itu, alih-alih rdmsr
, yang mengakses uncore
. Tapi itu tidak terlalu penting.
Kernel PMU event
hanya acara, yang diekspor ke sysfs
. Saya tidak tahu bagaimana hal ini dilakukan (secara otomatis oleh kernel semua PMC ditemukan pada sistem, atau hanya sesuatu yang sulit dikodekan, dan jika saya menambahkan kprobe
- apakah itu diekspor? Dll). Tetapi intinya adalah bahwa ini adalah peristiwa yang sama dengan Hardware event
atau yang lainnya dalam perf_event
sistem internal .
Dan saya tidak tahu apa itu
$ ls /sys/devices/uncore_cbox_0/events
clockticks
adalah.
Detail tentang Kernel PMU event
Pencarian melalui kode mengarah ke:
$ 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]);
- yang terjadi dalam fungsi
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]); ... }
}
dan perf_pmu__scan
berada di file yang sama:
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) {
...
pmu_read_sysfs(); // that's what it calls
}
- yang juga ada di file yang sama:
/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void) {...}
Itu dia.
Detail Hardware event
danHardware cache event
Rupanya, itu Hardware event
datang dari apa yang disebut Intel "Peristiwa Kinerja Arsitektur yang Telah Ditentukan", 18.2.1.2 dalam Manual Pengembang Perangkat Lunak IA-32 Vol 3B. Dan "18.1 TINJAUAN PEMANTAUAN KINERJA" dari manual menggambarkan mereka sebagai:
Kelas kedua kemampuan pemantauan kinerja disebut sebagai pemantauan kinerja arsitektur. Kelas ini mendukung penghitungan yang sama dan penggunaan pengambilan sampel acara berbasis interupsi, dengan rangkaian acara yang lebih kecil yang tersedia. Perilaku yang terlihat dari peristiwa kinerja arsitektur konsisten di seluruh implementasi prosesor. Ketersediaan kemampuan pemantauan kinerja arsitektur disebutkan menggunakan CPUID.0AH. Peristiwa ini dibahas dalam Bagian 18.2.
- tipe lainnya adalah:
Dimulai dengan Intel Core Solo dan prosesor Intel Core Duo, ada dua kelas kemampuan pemantauan kinerja. Kelas pertama mendukung acara untuk memantau kinerja menggunakan penghitungan atau penggunaan pengambilan sampel acara berbasis interupsi. Acara-acara ini non-arsitektur dan bervariasi dari satu model prosesor ke yang lain ...
Dan peristiwa ini memang hanya tautan ke peristiwa perangkat keras "mentah" yang mendasar, yang dapat diakses melalui perf
utilitas sebagai Raw hardware event descriptor
.
Untuk memeriksa ini lihat di 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,
...
}
- dan tepatnya 0x412e
ditemukan di "Tabel 18-1. Pengkodean Pilih UMask dan Peristiwa untuk Peristiwa Kinerja Arsitektur Pra-Didefinisikan" untuk "Misses LLC":
Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
4 | LLC Misses | 41H | 2EH
- H
untuk hex. Semua 7 berada dalam struktur, plus [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *
. (Penamaannya sedikit berbeda, alamatnya sama.)
Maka Hardware cache event
s berada dalam struktur seperti (dalam file yang sama):
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] =
{...}
- mana yang seharusnya untuk jembatan berpasir?
Salah satunya - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]
diisi dengan SNB_DMND_WRITE|SNB_L3_ACCESS
, di mana dari def-s di atas:
#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)
yang seharusnya sama dengan 0x00010102
, tapi saya tidak tahu bagaimana memeriksanya dengan beberapa tabel.
Dan ini memberikan gambaran bagaimana penggunaannya di 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));
$
The memcpy
s dilakukan dalam __init int intel_pmu_init(void) {... case:...}
.
Hanya attr->config1
sedikit aneh. Tapi itu ada di sana, di perf_event_attr
( linux-source-3.13.0/include/uapi/linux/perf_event.h
file yang sama ):
...
union {
__u64 bp_addr;
__u64 config1; /* extension of config */
};
union {
__u64 bp_len;
__u64 config2; /* extension of config1 */
};
...
Mereka terdaftar di perf_events
sistem kernel dengan panggilan ke int perf_pmu_register(struct pmu *pmu, const char *name, int type)
(didefinisikan dalam linux-source-3.13.0/kernel/events/core.c:
):
static int __init init_hw_perf_events(void)
(file arch/x86/kernel/cpu/perf_event.c
) dengan panggilanperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
(file arch/x86/kernel/cpu/perf_event_intel_uncore.c
, ada juga arch/x86/kernel/cpu/perf_event_amd_uncore.c
) dengan panggilanret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
Jadi akhirnya, semua acara berasal dari perangkat keras dan semuanya baik-baik saja. Tapi di sini orang bisa melihat: mengapa kita harus LLC-loads
di perf list
dan tidak ubox1 LLC-loads
, karena ini adalah peristiwa HW dan mereka sebenarnya berasal dari ubox
es?
Itu adalah bagian dari perf
utilitas dan perf_evsel
strukturnya: ketika Anda meminta acara HW dari perf
Anda menentukan acara dari mana prosesor yang Anda inginkan (default adalah semua), dan itu mengatur perf_evsel
dengan acara dan prosesor yang diminta, kemudian pada agregasi adalah menjumlahkan penghitung dari semua prosesor di perf_evsel
(atau melakukan beberapa statistik lain dengan mereka).
Orang dapat melihatnya di 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;
}
(Jadi, untuk utilitas, perf
"penghitung tunggal" bahkan bukan perf_event_attr
, yang merupakan bentuk umum, pas untuk acara SW dan HW, ini adalah acara permintaan Anda - acara yang sama dapat berasal dari perangkat yang berbeda dan mereka digabungkan .)
Juga pemberitahuan: struct perf_evsel
hanya berisi 1 struct perf_evevent_attr
, tetapi juga memiliki bidang struct perf_evsel *leader;
- bersarang. Ada fitur "kelompok acara (hierarkis)" di perf_events
, ketika Anda dapat mengirim sekelompok penghitung bersama-sama, sehingga mereka dapat dibandingkan satu sama lain dan seterusnya. Tidak yakin cara kerjanya dengan peristiwa independen dari kernel
, core
, ubox
. Tapi ini bersarang perf_evsel
. Dan, kemungkinan besar, itulah cara perf
mengelola kueri beberapa acara bersama.