Гугл і ack-інг закінчено! У мене є відповідь.
Але спочатку дозвольте мені ще трохи уточнити мету питання: я хочу чітко розмежувати незалежні процеси в системі та їх лічильники ефективності. Наприклад, ядро процесора, некомерційний пристрій (про це дізналися недавно), ядро або користувацька програма на процесорі, шина (= контролер шини), жорсткий диск - це все незалежні процеси, вони не синхронізуються годинником . І сьогодні, ймовірно, всі вони мають лічильник моніторингу процесів (PMC). Я хотів би зрозуміти, з яких процесів надходять лічильники. (Це також корисно в гуглінгу: "постачальник" речі нуліть це краще.)
Крім того , передача використовується для пошуку: Ubuntu 14.04, linux 3.13.0-103-generic, процесор Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz(з /proc/cpuinfo, він має 2 фізичних ядра і 4 віртуальних - фізична матерія тут).
Термінологія, що стосується питання
Від Intel:
процесор - це coreпристрій (це 1 пристрій / процес) і купа uncoreпристроїв - coreце те, що запускає програму (годинник, ALU, регістри тощо), uncoreце пристрої, які ставлять на штамп, близькі до процесора за швидкістю та низькою затримкою (справжня причина є "тому що виробник може це зробити"); як я зрозумів, це в основному Northbridge, як на материнській платі ПК, плюс кеші; AMD насправді називає ці пристрої NorthBridge instead ofuncore`;
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
- це uncoreпристрій, який керує кешем останнього рівня (LLC, останній перед тим, як потрапляти на ОЗУ); У мене 2 ядра, таким чином, 2 ТОВ і 2 ubox;
Блок моніторингу процесорів (PMU) - це окремий пристрій, який здійснює моніторинг операцій процесора і записує їх у лічильник моніторингу процесорів (PMC) (рахує пропуски кешу, цикли процесора тощо); вони існують на coreі uncoreпристроях; до coreних звертаються rdpmc(читайте PMC) інструкцію; uncore, Так як ці пристрої залежить від фактичного процесора під рукою, доступні через моделезавісімие регістри (MSR) через rdmsr(природно);
Мабуть, робочий процес з ними здійснюється за допомогою пар регістрів - 1 набір реєстрів, який позначає лічильник, 2 регістр - це значення в лічильнику; лічильник може бути налаштований на приріст після ряду подій, а не лише 1; + в цих лічильниках є деякі переривання / техніка, що помічають переповнення;
більше ви можете знайти в Інструкції Intel «IA-32 Software Developer Guide» Vol 3B »глави 18« МОНИТОРИНГ РОБОТИ »;
також формат MSR конкретно для цих uncoreПМК для версії "Архітектурний моніторинг продуктивності версії 1" (в посібнику є версії 1-4, я не знаю, який з них є моїм процесором) описаний у "Рисунок 18-1. Макет з MSR IA32_PERFEVTSELx "(сторінка 18-3 в шахті) та розділ" 18.2.1.2 Заздалегідь визначені події архітектурної ефективності "з" Таблиця 18-1. Кодування вибору UMask та подій для заздалегідь визначених подій архітектурної діяльності ", на якій показано події, які відображаються як Hardware eventу perf list.
З ядра Linux:
ядро має систему (абстракція / шар) для управління лічильниками продуктивності різного походження, як програмного забезпечення (ядра), так і апаратного забезпечення, в ньому описано 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поле - вона може містити як специфічне для процесора визначення події (64-бітове слово у форматі, описаному на рисунках цих Intel), так і подія ядра
MSB слова config означає, що решта містить [raw 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це мій псевдонім ack-grep, який є ім'ям для ackDebian; і ackце приголомшливо);
у вихідному коді ядра можна побачити такі операції, як "реєструвати всі ПМУ struct pmu, які є в системі," та типи структури , які передаються на щось подібне int perf_pmu_register(struct pmu *pmu, const char *name, int type)- таким чином, можна було б просто назвати цю систему "PMU ядра", що було б агрегацією всіх ПМУ в системі; але цю назву можна інтерпретувати як систему моніторингу операцій ядра, що було б оманливим;
назвемо цю підсистему perf_eventsдля ясності;
як і будь-яка підсистема ядра, цю підсистему можна експортувати в sysfs(що робиться для експорту ядра підсистем для використання людьми); і ось які це eventsкаталоги в моїй /sys/- експортованій (частини?) 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утиліта призначає подію всім або певним процесорам.
Відповідь
Дійсно, Hardware cache eventце "ярлики" до подій кеш-пристроїв (пристроїв uboxIntel uncore), які залежать від процесора, і до них можна отримати доступ через протокол Raw hardware event descriptor. І Hardware eventвони стабільніші в архітектурі, які, як я розумію, називають події з coreпристрою. У моєму ядрі немає інших "ярликів" 3.13до якихось інших uncoreподій та лічильників. Всі інші - Softwareі Tracepoints- події ядра.
Цікаво , якщо core«S Hardware events доступні через той же Raw hardware event descriptorпротокол. Вони можуть - ні, оскільки лічильник / PMU сидить core, можливо, до нього звертаються інакше. Наприклад, rdpmuзамість тієї інструкції rdmsr, яка отримує доступ uncore. Але це не так важливо.
Kernel PMU event- це лише події, в які експортуються sysfs. Я не знаю, як це робиться (автоматично ядром усі виявлені ПМС в системі, або просто щось жорстко закодоване, і якщо я додам 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походження від того, що Intel називає «Попередньо визначеними подіями архітектурної ефективності», 18.2.1.2 в Посібнику розробника програмного забезпечення IA-32, Vol 3B. І "Огляд огляду моніторингу виконання 18.1" описує їх як:
Другий клас можливостей моніторингу продуктивності називають архітектурним моніторингом ефективності. Цей клас підтримує ті ж самі підрахунки подій для відбору проб на основі переривань, з меншим набором доступних подій. Видима поведінка подій архітектурної продуктивності узгоджується у всіх процесорах. Наявність можливостей контролю архітектури продуктивності перераховується за допомогою CPUID.0AH. Ці події обговорюються у розділі 18.2.
- інший тип:
Починаючи з процесорів Intel Core Solo та Intel Core Duo, є два класи можливостей моніторингу продуктивності. Перший клас підтримує події для моніторингу продуктивності з використанням підрахунку або використання вибірок на основі переривань. Ці події є не архітектурними і відрізняються від однієї моделі процесора до іншої ...
І ці події справді є лише посиланнями на основні "сирі" апаратні події, до яких можна отримати доступ за допомогою 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знайдено в "Таблиці 18-1. Кодування вибору UMask та подій для заздалегідь визначених подій архітектурної ефективності" для "LLC Misses":
Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
4 | LLC Misses | 41H | 2EH
- Hце для hex. Усі 7 в структурі, плюс [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (Найменування дещо інше, адреси однакові.)
Тоді Hardware cache events знаходяться в таких структурах, як (у тому самому файлі):
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] =
{...}
- що має бути для піщаного мосту?
Одне з них - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]заповнене SNB_DMND_WRITE|SNB_L3_ACCESS, де з вищезазначених задач:
#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));
$
В memcpys зроблені в __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 події , і вони actualy приходять з uboxес?
Це справа perfутиліти та її perf_evselструктури: коли ви вимагаєте від події HW, perfви визначаєте подію, від яких процесорів ви хочете це (за замовчуванням це все), і вона встановлює 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керується запитом кількох подій разом.