Jakie są zdarzenia jądra PMU na liście perf_events?

11

Szukając tego, co można monitorować perf_eventsw systemie Linux, nie mogę znaleźć, co to Kernel PMU eventjest? Mianowicie, z perf version 3.13.11-ckt39tych perf listpokazów wydarzeń, takich jak:

branch-instructions OR cpu/branch-instructions/    [Kernel PMU event]

Ogólnie są to:

Tracepoint event
Software event
Hardware event
Hardware cache event
Raw hardware event descriptor
Hardware breakpoint
Kernel PMU event

i chciałbym zrozumieć, czym one są, skąd pochodzą. Mam jakieś wyjaśnienie dla wszystkich, ale Kernel PMU eventprzedmiot.

Z samouczka perf wiki i strony Brendana Gregga otrzymuję:

  • Tracepointssą najczystsze - są to makra w źródle jądra, które stanowią punkt próbny do monitorowania, zostały wprowadzone wraz z ftraceprojektem i teraz są używane przez wszystkich
  • Software są licznikami niskiego poziomu jądra i niektórymi wewnętrznymi strukturami danych (stąd różnią się od punktów śledzenia)
  • Hardware eventsą bardzo podstawowymi zdarzeniami procesora, znajdowanymi na wszystkich architekturach i dostępnymi przez jądro
  • Hardware cache eventsą pseudonimy dla Raw hardware event descriptor- działa w następujący sposób

    zgodnie z tym, co otrzymałem, Raw hardware event descriptorsą bardziej specyficzne dla architektury (mikro?) zdarzenia niż Hardware eventzdarzenia pochodzą z jednostki monitorowania procesora (PMU) lub innych specyficznych cech danego procesora, dlatego są dostępne tylko na niektórych mikroarchitekturach (powiedzmy „ architektura ”oznacza„ x86_64 ”, a wszystkie pozostałe szczegóły implementacji to„ mikroarchitektura ”); i są dostępne do instrumentacji za pomocą tych dziwnych deskryptorów

    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)
    

    - deskryptory, na które zdarzenia wskazują i tak dalej, znajdują się w instrukcjach procesorów ( zdarzenia PMU w perf wiki );

    ale kiedy ludzie wiedzą, że na danym procesorze znajduje się jakieś użyteczne zdarzenie, nadają mu pseudonim i podłączają go do systemu Linux, Hardware cache eventaby ułatwić dostęp

    - popraw mnie, jeśli się mylę (o dziwo wszyscy Hardware cache eventsą o something-loadslub something-misses- bardzo podobnie jak pamięć podręczna procesora ..)

  • teraz Hardware breakpoint

    mem:<addr>[:access]                                [Hardware breakpoint]
    

    jest cechą sprzętową, która prawdopodobnie jest wspólna dla większości współczesnych architektur i działa jako punkt przerwania w debuggerze? (prawdopodobnie i tak można googlować)

  • wreszcie Kernel PMU eventnie udaje mi się google;

    nie pojawia się również na liście wydarzeń na stronie perf Brendana , więc jest nowy?

    Może to tylko pseudonimy dla wydarzeń sprzętowych, szczególnie z PMU? (Dla ułatwienia dostępu ma on osobną sekcję na liście zdarzeń oprócz pseudonimu.) W rzeczywistości może Hardware cache eventssą pseudonimy dla zdarzeń sprzętowych z pamięci podręcznej procesora i Kernel PMU eventsą pseudonimami dla zdarzeń PMU? (Dlaczego więc go nie nazwać Hardware PMU event?). Może to być po prostu nowy schemat nazewnictwa - pseudonimy dla zdarzeń sprzętowych zostały podzielone na sekcje?

    Te zdarzenia odnoszą się do takich rzeczy, jak również cpu/mem-stores/, ponieważ niektóre wydarzenia w wersji dla systemu Linux mają opisy w /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/tracingjest dla ftracei tracepoints, inne katalogi pasują dokładnie tak perf list, jak pokazuje Kernel PMU event.

Mógłby mi ktoś punkt w dobrym Wyjaśnienie / dokumentacji co Kernel PMU eventslub /sys/..events/systemy są? Czy jest /sys/..events/jakiś nowy wysiłek w celu usystematyzowania zdarzeń sprzętowych czy coś podobnego? (Zatem jądro PMU przypomina „jednostkę monitorowania wydajności jądra”.)

PS

Aby dać lepszy kontekst, nieuprzywilejowane uruchomienie perf list(tracepoints nie są pokazane, ale wszystkie 1374 z nich są tam) z pełną listą Kernel PMU events i Hardware cache eventsi pominięto:

$ 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 ]
xealits
źródło

Odpowiedzi:

11

Googling i ack-ing się skończyły! Mam odpowiedź.

Ale najpierw pozwól, że wyjaśnię nieco cel pytania: chcę wyraźnie odróżnić niezależne procesy w systemie i ich liczniki wydajności. Na przykład rdzeń procesora, urządzenie uncore (o tym niedawno się dowiedziałem), jądro lub aplikacja użytkownika na procesorze, magistrala (= kontroler magistrali), dysk twardy są niezależnymi procesami, nie są synchronizowane przez zegar . I obecnie prawdopodobnie każdy z nich ma jakiś licznik monitorowania procesu (PMC). Chciałbym zrozumieć, z których procesów pochodzą te liczniki. (Jest to również pomocne w googlowaniu: „sprzedawca” rzeczy zeruje to lepiej.)

Również sprzętu wykorzystywanego do szukania: Ubuntu 14.04, linux 3.13.0-103-generic, procesor Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz(z /proc/cpuinfo, posiada 2 rdzenie fizyczne i 4 wirtualne - fizyczne materii tutaj).

Terminologia, rzeczy, które obejmuje pytanie

Od Intela:

  • procesor to coreurządzenie (to 1 urządzenie / proces) i kilka uncoreurządzeń , coreto, co uruchamia program (zegar, ALU, rejestry itp.), uncoresą urządzeniami umieszczanymi na matrycy, blisko procesora ze względu na szybkość i małe opóźnienia (prawdziwy powód to „ponieważ producent może to zrobić”); jak zrozumiałem, jest to w zasadzie mostek północny, jak na płycie głównej komputera, plus pamięci podręczne; a AMD faktycznie nazywa te urządzenia NorthBridge instead ofuncore`;

  • ubox co pojawia się w moim sysfs

    $ find /sys/devices/ -type d -name events 
    /sys/devices/cpu/events
    /sys/devices/uncore_cbox_0/events
    /sys/devices/uncore_cbox_1/events
    

    - jest uncoreurządzeniem, które zarządza pamięcią podręczną ostatniego poziomu (LLC, ostatnia przed uderzeniem w pamięć RAM); Mam 2 rdzenie, a więc 2 LLC i 2 ubox;

  • Processor Monitoring Unit (PMU) to oddzielne urządzenie, które monitoruje operacje procesora i zapisuje je w liczniku monitorowania procesora (PMC) (zlicza błędy pamięci podręcznej, cykle procesora itp.); one istnieć corei uncoreurządzeń; z corenich są dostępne z rdpmc(czytaj PMC) pouczenie; uncore, ponieważ urządzenia te zależą od rzeczywistego procesorów w parze są dostępne poprzez modele rejestrów szczególne (MSR) poprzez rdmsr(naturalny);

    najwyraźniej przepływ pracy z nimi odbywa się za pomocą par rejestrów - 1 rejestr ustawia zdarzenia, które liczy licznik, 2 rejestr jest wartością w liczniku; licznik można skonfigurować tak, aby zwiększał wartość po kilku zdarzeniach, nie tylko 1; + w tych licznikach występują interupty / zauważające przepełnienie technologiczne;

  • więcej można znaleźć w „Intel IA-32 Software Developer's Manual Vol. 3B” rozdział 18 „MONITOROWANIE WYDAJNOŚCI”;

    także format MSR konkretnie dla tych uncorePMC dla wersji „Architectural Performance Monitoring Version 1” (istnieją wersje 1-4 w instrukcji, nie wiem, który to mój procesor) jest opisany na „Rysunek 18-1. MSR IA32_PERFEVTSELx ”(strona 18-3 w kopalni) oraz sekcja„ 18.2.1.2 Wstępnie zdefiniowane zdarzenia wydajności architektonicznej ”w„ Tabeli 18-1. UMask i kodowanie wybranych zdarzeń dla wstępnie zdefiniowanych zdarzeń wydajności architektonicznej ”, która pokazuje wydarzenia, które pojawiają się jak Hardware eventw perf list.

Z jądra Linux:

  • jądro ma system (abstrakcja / warstwa) do zarządzania licznikami wydajności różnego pochodzenia, zarówno oprogramowania (jądra), jak i sprzętu, co opisano w linux-source-3.13.0/tools/perf/design.txt; zdarzenie w tym systemie jest zdefiniowane jako struct perf_event_attr(plik linux-source-3.13.0/include/uapi/linux/perf_event.h), którego główna część jest prawdopodobnie __u64 configpolowa - może zawierać zarówno definicję zdarzenia specyficzną dla procesora (64-bitowe słowo w formacie opisanym na tych liczbach Intela), jak i zdarzenie jądra

    MSB słowa konfiguracyjnego oznacza, że ​​reszta zawiera [nieprzetworzone zdarzenie procesora lub jądra]

    zdarzenie jądra zdefiniowane za pomocą 7 bitów dla typu i 56 dla identyfikatora zdarzenia, które są enum-s w kodzie, które w moim przypadku to:

    $ 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 */
    

    ( akto mój pseudonim na ack-grep, który nazywa się ackna Debianie; i ackjest niesamowity);

    w kodzie źródłowym jądra widać operacje takie jak „rejestruj wszystkie PMU odkryte w systemie” i typy struktur struct pmu, które są przekazywane do czegoś podobnego int perf_pmu_register(struct pmu *pmu, const char *name, int type)- w ten sposób można nazwać ten system „PMU jądra”, co byłoby agregacją wszystkich PMU w systemie; ale ta nazwa może być interpretowana jako system monitorowania operacji jądra, co byłoby mylące;

    nazwijmy ten podsystem perf_eventsdla jasności;

  • jak każdy podsystem jądra, ten podsystem można wyeksportować do sysfs(który jest przeznaczony do eksportu podsystemów jądra do użytku przez ludzi); i to są te eventskatalogi w moim /sys/- eksportowanym (częściach) perf_eventspodsystemie;

  • ponadto narzędzie przestrzeni użytkownika perf(wbudowane w system Linux) jest nadal osobnym programem i ma własne „abstrakcje”; reprezentuje zdarzenie wymagane do monitorowania przez użytkownika jako perf_evsel(pliki linux-source-3.13.0/tools/perf/util/evsel.{h,c}) - ta struktura ma pole struct perf_event_attr attr;, ale także pole podobne do struct cpu_map *cpus;tego, w jaki sposób perfnarzędzie przypisuje zdarzenie do wszystkich lub poszczególnych procesorów.

Odpowiedź

  1. Rzeczywiście, Hardware cache eventsą to „skróty” do zdarzeń urządzeń pamięci podręcznej (urządzeń uboxIntela uncore), które są specyficzne dla procesora i można uzyskać do nich dostęp za pośrednictwem protokołu Raw hardware event descriptor. I Hardware eventsą bardziej stabilne w architekturze, która, jak rozumiem, nazywa zdarzenia z coreurządzenia. W moim jądrze nie ma innych „skrótów” 3.13do niektórych innych uncorezdarzeń i liczników. Cała reszta - Softwarei Tracepoints- są zdarzeniami jądra.

    Zastanawiam się, czy core„s Hardware events są dostępne za pośrednictwem tego samego Raw hardware event descriptorprotokołu. Mogą nie - ponieważ licznik / PMU jest włączony core, być może dostęp do niego jest inny. Na przykład z tą rdpmuinstrukcją, zamiast rdmsr, która uzyskuje dostęp uncore. Ale to nie jest takie ważne.

  2. Kernel PMU eventsą tylko wydarzeniami, na które są eksportowane sysfs. Nie wiem, jak to się robi (automatycznie przez jądro wszystkie wykryte PMC w systemie lub po prostu coś na stałe zakodowanego, a jeśli dodam kprobe- czy to jest eksportowane? Itp.). Ale najważniejsze jest to, że są to te same zdarzenia, które Hardware eventwystępują w systemie wewnętrznym perf_event.

    I nie wiem co to

    $ ls /sys/devices/uncore_cbox_0/events
    clockticks
    

    są.

Szczegóły dotyczące Kernel PMU event

Przeszukiwanie kodu prowadzi do:

$ 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]);

- co dzieje się w funkcji

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]); ... }
}

i perf_pmu__scanznajduje się w tym samym pliku:

struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) {
    ...
                pmu_read_sysfs(); // that's what it calls
}

- który również znajduje się w tym samym pliku:

/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void) {...}

Otóż ​​to.

Szczegóły dotyczące Hardware eventiHardware cache event

Najwyraźniej Hardware eventpochodzą od tego, co Intel nazywa „wstępnie zdefiniowanymi zdarzeniami dotyczącymi wydajności architektonicznej”, 18.2.1.2 w IA-32 Software Developer's Manual tom 3B. I „PRZEGLĄD MONITOROWANIA WYDAJNOŚCI 18.1” instrukcji opisuje je jako:

Druga klasa możliwości monitorowania wydajności jest określana jako monitorowanie wydajności architektury. Ta klasa obsługuje takie same sposoby liczenia i próbkowania zdarzeń w oparciu o przerwanie, z mniejszym zestawem dostępnych zdarzeń. Widoczne zachowanie architektonicznych zdarzeń wydajnościowych jest spójne we wszystkich implementacjach procesorów. Dostępność funkcji monitorowania wydajności architektury jest wyliczana przy użyciu CPUID.0AH. Wydarzenia te zostały omówione w rozdziale 18.2.

- drugi typ to:

Począwszy od procesorów Intel Core Solo i Intel Core Duo, istnieją dwie klasy możliwości monitorowania wydajności. Pierwsza klasa obsługuje zdarzenia do monitorowania wydajności przy użyciu liczenia lub próbkowania zdarzeń na podstawie przerwania. Te zdarzenia nie mają charakteru architektonicznego i różnią się w zależności od modelu procesora ...

I te zdarzenia są po prostu linkami do podstawowych „surowych” zdarzeń sprzętowych, do których można uzyskać dostęp za pomocą perfnarzędzia as Raw hardware event descriptor.

Aby to sprawdzić, spójrz na 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,
    ...
}

- i dokładnie 0x412eznajduje się w „Tabeli 18-1. UMask i kodowanie wyboru zdarzeń dla wstępnie zdefiniowanych zdarzeń wydajności architektonicznej” dla „Braków LLC”:

Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
                        4 | LLC Misses | 41H   | 2EH

- Hdotyczy heksa. Wszystkie 7 są w strukturze, plus [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (Nazewnictwo jest nieco inne, adresy są takie same).

Zatem Hardware cache events są w strukturach takich jak (w tym samym pliku):

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] =
{...}

- który powinien być na piaszczysty most?

Jeden z nich - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]jest wypełniony SNB_DMND_WRITE|SNB_L3_ACCESS, gdzie z def-s powyżej:

#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)

co powinno być równe 0x00010102, ale nie wiem, jak to sprawdzić za pomocą jakiejś tabeli.

A to daje wyobrażenie o tym, jak jest używany w 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));
$

Do memcpys wykonywane są w __init int intel_pmu_init(void) {... case:...}.

To tylko attr->config1trochę dziwne. Ale jest tam, w perf_event_attr(ten sam linux-source-3.13.0/include/uapi/linux/perf_event.hplik):

...
    union {
            __u64           bp_addr;
            __u64           config1; /* extension of config */                                                      
    };
    union {
            __u64           bp_len;
            __u64           config2; /* extension of config1 */
    };
...

Są rejestrowane w perf_eventssystemie jądra za pomocą wywołań int perf_pmu_register(struct pmu *pmu, const char *name, int type)(zdefiniowanych w linux-source-3.13.0/kernel/events/core.c:):

  • static int __init init_hw_perf_events(void)(plik arch/x86/kernel/cpu/perf_event.c) z połączeniemperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

  • static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)(plik arch/x86/kernel/cpu/perf_event_intel_uncore.c, są też arch/x86/kernel/cpu/perf_event_amd_uncore.c) z połączeniemret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

Wreszcie wszystkie zdarzenia pochodzą ze sprzętu i wszystko jest w porządku. Ale tutaj można zauważyć: dlaczego mamy LLC-loadsna perf listnie ubox1 LLC-loads, ponieważ są to wydarzenia HW i one właściwie pochodzą z uboxes?

Jest to rzecz związana z perfnarzędziem i jego perf_evselstrukturą: kiedy zażądasz od zdarzenia HW perf, zdefiniuj zdarzenie, z którego procesorów chcesz je uzyskać (domyślnie jest to wszystko), i ustawia perf_evselżądane zdarzenie i procesory, a następnie agregacja jest sumuje liczniki ze wszystkich procesorów w perf_evsel(lub robi z nimi inne statystyki).

Widać to w 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;
}

(Tak więc dla narzędzia perf„pojedynczy licznik” nie jest nawet a perf_event_attr, co jest formą ogólną, pasującą zarówno do zdarzeń SW, jak i HW, jest to zdarzenie z zapytania - te same zdarzenia mogą pochodzić z różnych urządzeń i są agregowane .)

Uwaga: struct perf_evselzawiera tylko 1 struct perf_evevent_attr, ale ma także pole struct perf_evsel *leader;- jest zagnieżdżone. Istnieje funkcja „(hierarchicznych) grup zdarzeń”, w perf_eventsktórych można wysyłać kilka liczników razem, aby można je było porównywać ze sobą i tak dalej. Nie wiem, jak to działa z niezależnych wydarzeń z kernel, core, ubox. Ale to jest zagnieżdżanie perf_evsel. I najprawdopodobniej w ten sposób perfzarządza kwerendą kilku zdarzeń razem.

xealits
źródło