Was sind Kernel-PMU-Ereignisse in der Liste perf_events?

11

Auf der Suche nach dem, was man unter perf_eventsLinux überwachen kann , kann ich nicht finden, was Kernel PMU eventes ist? Nämlich mit perf version 3.13.11-ckt39den perf listShows Events wie:

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

Insgesamt gibt es:

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

und ich würde gerne verstehen, was sie sind, woher sie kommen. Ich habe eine Erklärung für alle, aber Kernel PMU eventPunkt.

Aus dem Perf Wiki Tutorial und der Seite von Brendan Gregg geht Folgendes hervor :

  • Tracepointssind die klarsten - dies sind Makros auf der Kernelquelle, die einen Prüfpunkt für die Überwachung darstellen. Sie wurden mit dem ftraceProjekt eingeführt und werden jetzt von allen verwendet
  • Software sind Kernel-Low-Level-Zähler und einige interne Datenstrukturen (daher unterscheiden sie sich von Tracepoints).
  • Hardware eventsind einige sehr grundlegende CPU-Ereignisse, die auf allen Architekturen zu finden sind und auf die der Kernel irgendwie leicht zugreifen kann
  • Hardware cache eventsind Spitznamen zu Raw hardware event descriptor- es funktioniert wie folgt

    Wie ich es verstanden habe, handelt Raw hardware event descriptores sich um mehr (Mikro-?) architekturspezifische Ereignisse als um Hardware eventEreignisse, die von der Prozessorüberwachungseinheit (PMU) oder anderen spezifischen Merkmalen eines bestimmten Prozessors stammen. Daher sind sie nur auf einigen Mikroarchitekturen verfügbar (sagen wir " Architektur "bedeutet" x86_64 "und alle übrigen Implementierungsdetails sind" Mikroarchitektur "); und sie sind für die Instrumentierung über diese seltsamen Deskriptoren zugänglich

    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)
    

    - Diese Deskriptoren, auf welche Ereignisse sie verweisen usw., finden Sie in den Handbüchern des Prozessors ( PMU-Ereignisse im Perf-Wiki ).

    Aber wenn die Leute wissen, dass es auf einem bestimmten Prozessor ein nützliches Ereignis gibt, geben sie ihm einen Spitznamen und schließen ihn an Linux Hardware cache eventan, um den Zugriff zu erleichtern

    - Korrigieren Sie mich, wenn ich falsch liege (seltsamerweise handelt es sich bei allen Hardware cache eventum something-loadsoder something-misses- sehr ähnlich dem Cache des eigentlichen Prozessors ..)

  • jetzt die Hardware breakpoint

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

    ist eine Hardwarefunktion, die wahrscheinlich den meisten modernen Architekturen gemeinsam ist und als Haltepunkt in einem Debugger fungiert? (wahrscheinlich ist es sowieso googlable)

  • Schließlich Kernel PMU eventschaffe ich es nicht, weiter zu googeln.

    es wird auch nicht in der Liste der Ereignisse auf Brendans Perf-Seite angezeigt , also ist es neu?

    Vielleicht sind es nur Spitznamen für Hardware-Ereignisse speziell von PMU? (Um den Zugriff zu vereinfachen, wurde zusätzlich zum Spitznamen ein separater Abschnitt in der Liste der Ereignisse angezeigt.) Sind möglicherweise tatsächlich Hardware cache eventsSpitznamen für Hardwareereignisse aus dem CPU-Cache und Kernel PMU eventSpitznamen für PMU-Ereignisse? (Warum nennst Hardware PMU eventdu es dann nicht? ..) Es könnte nur ein neues Namensschema sein - die Spitznamen für Hardwareereignisse wurden unterteilt?

    Und diese Ereignisse beziehen sich auf Dinge wie, außerdem cpu/mem-stores/, da einige Ereignisse der Linux-Version Beschreibungen in /sys/devices/und haben:

    # 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/tracingist für ftraceund Tracepoints, andere Verzeichnisse stimmen genau mit dem überein, was perf listals angezeigt wird Kernel PMU event.

Könnte mich jemand auf eine gute Erklärung / Dokumentation dessen hinweisen, was Kernel PMU eventsoder welche /sys/..events/Systeme sind? Gibt es auch /sys/..events/neue Anstrengungen, um Hardware-Ereignisse oder ähnliches zu systematisieren? (Dann ist die Kernel-PMU wie "die Leistungsüberwachungseinheit des Kernels".)

PS

Um einen besseren Kontext zu perf listbieten , wird eine nicht privilegierte Ausführung von (Tracepoints werden nicht angezeigt, aber alle 1374 sind vorhanden) mit vollständigen Auflistungen von Kernel PMU events und Hardware cache events und anderen übersprungen:

$ 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
quelle

Antworten:

11

Googeln und ack-ing ist vorbei! Ich habe eine Antwort.

Lassen Sie mich zunächst das Ziel der Frage etwas näher erläutern: Ich möchte unabhängige Prozesse im System und ihre Leistungsindikatoren klar unterscheiden. Zum Beispiel sind ein Kern eines Prozessors, ein Uncore-Gerät (das kürzlich kennengelernt wurde), ein Kernel oder eine Benutzeranwendung auf dem Prozessor, ein Bus (= Bus-Controller) und eine Festplatte unabhängige Prozesse, die nicht durch eine Uhr synchronisiert werden . Und heutzutage haben wahrscheinlich alle einen Process Monitoring Counter (PMC). Ich würde gerne verstehen, aus welchen Prozessen die Zähler stammen. (Es ist auch hilfreich beim Googeln: Der "Verkäufer" einer Sache setzt es besser auf Null.)

Auch das Getriebe für die Suche: Ubuntu 14.04, linux 3.13.0-103-generic, Prozessor Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz(ab /proc/cpuinfo, es verfügt über 2 physische Kerne und 4 virtuelle - die physische Materie hier).

Terminologie, Dinge, die die Frage beinhaltet

Von Intel:

  • Der Prozessor ist ein coreGerät (es ist 1 Gerät / Prozess) und eine Reihe von uncoreGeräten . Er coreführt das Programm aus (Uhr, ALU, Register usw.). Er uncoreist ein Gerät, das aus Gründen der Geschwindigkeit und der geringen Latenz in der Nähe des Prozessors auf den Chip gestellt wird (der wahre Grund) ist "weil der Hersteller das kann"); Wie ich verstanden habe, handelt es sich im Grunde genommen um die Northbridge, wie auf einem PC-Motherboard, plus Caches. und AMD nennt diese Geräte tatsächlich NorthBridge instead ofuncore`;

  • ubox was sich in meinem zeigt sysfs

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

    - ist ein uncoreGerät, das den Last Level Cache (LLC, den letzten vor dem Erreichen des RAM) verwaltet; Ich habe 2 Kerne, also 2 LLC und 2 ubox;

  • Die Prozessorüberwachungseinheit (PMU) ist ein separates Gerät, das die Operationen eines Prozessors überwacht und diese im Prozessorüberwachungszähler (PMC) aufzeichnet (zählt Cache-Fehler, Prozessorzyklen usw.). sie existieren auf coreund uncoreGeräte; Auf diese wird mit der Anweisung (PMC lesen) corezugegriffen rdpmc. die uncore, da diese Geräte auf dem tatsächlichen Prozessor zur Hand abhängen, wird über Modell spezifische Register (MSR) über zugegriffen rdmsr(natürlich);

    anscheinend erfolgt der Workflow mit ihnen über Registerpaare - 1 Registersatz, welche Ereignisse der Zähler zählt, 2 Register ist der Wert im Zähler; Der Zähler kann so konfiguriert werden, dass er nach einer Reihe von Ereignissen inkrementiert wird, nicht nur nach 1. + Es gibt einige Interrupts / Tech, die Überläufe in diesen Zählern bemerken.

  • Weitere Informationen finden Sie in Intels "IA-32 Software Developer's Manual Vol 3B", Kapitel 18 "PERFORMANCE MONITORING".

    Das MSR-Format für diese uncorePMCs für die Version "Architectural Performance Monitoring Version 1" (es gibt die Versionen 1 bis 4 im Handbuch, ich weiß nicht, welcher mein Prozessor ist) ist in "Abbildung 18-1. Layout" beschrieben von IA32_PERFEVTSELx-MSRs "(Seite 18-3 in meinem) und Abschnitt" 18.2.1.2 Vordefinierte Architekturleistungsereignisse "mit" Tabelle 18-1. UMask- und Ereignisauswahlcodierungen für vordefinierte Architekturleistungsereignisse ", in denen die Ereignisse, die wie Hardware eventin angezeigt werden perf list.

Vom Linux-Kernel:

  • Der Kernel verfügt über ein System (Abstraktion / Schicht) zum Verwalten von Leistungsindikatoren unterschiedlichen Ursprungs, sowohl Software (Kernel) als auch Hardware linux-source-3.13.0/tools/perf/design.txt. Ein Ereignis in diesem System ist definiert als struct perf_event_attr(Datei linux-source-3.13.0/include/uapi/linux/perf_event.h), dessen Hauptteil wahrscheinlich ein __u64 configFeld ist. Es kann sowohl eine CPU-spezifische Ereignisdefinition (das 64-Bit-Wort in dem in den Intel-Abbildungen beschriebenen Format) als auch ein Kernel-Ereignis enthalten

    Das MSB des Konfigurationsworts gibt an, ob der Rest [das Ereignis der rohen CPU oder des Kernels] enthält.

    Das Ereignis des Kernels, das mit 7 Bits für den Typ und 56 für die Kennung des Ereignisses definiert ist. enumDies sind -s im Code. In meinem Fall sind dies:

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

    ( akist mein Alias ​​für ack-grep, was der Name für ackDebian ist; und ackist fantastisch);

    Im Quellcode des Kernels sieht man Operationen wie "Alle auf dem System entdeckten PMUs registrieren" und Strukturtypen struct pmu, die an so etwas wie übergeben int perf_pmu_register(struct pmu *pmu, const char *name, int type)werden. Man könnte dieses System also einfach "PMU des Kernels" nennen, was eine Aggregation wäre aller PMUs im System; Dieser Name könnte jedoch als Überwachungssystem für die Kerneloperationen interpretiert werden, was irreführend wäre.

    Nennen wir dieses Subsystem der perf_eventsKlarheit halber.

  • Wie jedes Kernel-Subsystem kann dieses Subsystem exportiert werden sysfs(das zum Exportieren von Kernel-Subsystemen für Benutzer bestimmt ist). und das sind diese eventsVerzeichnisse in meinem /sys/- dem exportierten (Teile von?) perf_eventsSubsystem;

  • Außerdem ist das User-Space-Dienstprogramm perf(in Linux integriert) immer noch ein separates Programm und verfügt über eigene Abstraktionen. Es stellt ein Ereignis dar, das vom Benutzer als perf_evsel(Dateien linux-source-3.13.0/tools/perf/util/evsel.{h,c}) überwacht werden soll. Diese Struktur enthält ein Feld struct perf_event_attr attr;, aber auch ein Feld struct cpu_map *cpus;, in dem das perfDienstprogramm allen oder bestimmten CPUs ein Ereignis zuweist.

Antworten

  1. In der Tat handelt Hardware cache eventes sich um "Verknüpfungen" zu den Ereignissen der Cache-Geräte ( uboxder Intel- uncoreGeräte), die prozessorspezifisch sind und über das Protokoll aufgerufen werden können Raw hardware event descriptor. Und Hardware eventsind innerhalb der Architektur stabiler, die, wie ich verstehe, die Ereignisse vom coreGerät benennen . In meinem Kernel gibt es keine anderen "Verknüpfungen" 3.13zu anderen uncoreEreignissen und Zählern. Alles andere - Softwareund Tracepoints- sind Kernel-Ereignisse.

    Ich frage mich , ob die core‚s Hardware events über das gleiche Zugriff Raw hardware event descriptorProtokoll. Möglicherweise nicht - da der Zähler / die PMU aktiviert ist core, wird möglicherweise anders darauf zugegriffen. Zum Beispiel mit dieser rdpmuAnweisung anstelle von rdmsr, auf die zugegriffen wird uncore. Aber es ist nicht so wichtig.

  2. Kernel PMU eventsind nur die Ereignisse, in die exportiert wird sysfs. Ich weiß nicht, wie das gemacht wird (automatisch vom Kernel alle entdeckten PMCs auf dem System oder nur etwas fest codiertes, und wenn ich ein hinzufüge kprobe- wird es exportiert? Usw.). Der Hauptpunkt ist jedoch, dass dies dieselben Ereignisse wie Hardware eventoder andere im internen perf_eventSystem sind.

    Und ich weiß nicht was das ist

    $ ls /sys/devices/uncore_cbox_0/events
    clockticks
    

    sind.

Details zu Kernel PMU event

Das Durchsuchen des Codes führt zu:

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

- was in der Funktion passiert

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

und perf_pmu__scanist in der gleichen Datei:

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

- das ist auch in der gleichen Datei:

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

Das ist es.

Details zu Hardware eventundHardware cache event

Anscheinend Hardware eventstammen die von Intel als "vordefinierte architektonische Leistungsereignisse", 18.2.1.2 im IA-32 Software Developer's Manual Vol 3B. Und "18.1 ÜBERBLICK ÜBER DIE LEISTUNGSÜBERWACHUNG" des Handbuchs beschreibt sie wie folgt:

Die zweite Klasse von Leistungsüberwachungsfunktionen wird als Architekturleistungsüberwachung bezeichnet. Diese Klasse unterstützt die gleiche Verwendung von Zähl- und Interrupt-basierten Ereignisabtastungen mit einem kleineren Satz verfügbarer Ereignisse. Das sichtbare Verhalten von Architekturleistungsereignissen ist bei allen Prozessorimplementierungen konsistent. Die Verfügbarkeit von Funktionen zur Überwachung der Architekturleistung wird mithilfe der CPUID.0AH aufgelistet. Diese Ereignisse werden in Abschnitt 18.2 erläutert.

- Der andere Typ ist:

Beginnend mit Intel Core Solo und Intel Core Duo Prozessoren gibt es zwei Klassen von Leistungsüberwachungsfunktionen. Die erste Klasse unterstützt Ereignisse zur Überwachung der Leistung mithilfe der Zählung oder der Verwendung von Interrupt-basierten Ereignisabtastungen. Diese Ereignisse sind nicht architektonisch und variieren von Prozessormodell zu Prozessor ...

Und diese Ereignisse sind in der Tat nur Links zu zugrunde liegenden "rohen" Hardwareereignissen, auf die über das perfDienstprogramm als zugegriffen werden kann Raw hardware event descriptor.

Um dies zu überprüfen, schaut man sich an 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,
    ...
}

- und genau 0x412efinden Sie in "Tabelle 18-1. UMask- und Ereignisauswahlcodierungen für vordefinierte architektonische Leistungsereignisse" für "LLC Misses":

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

- Hist für hex. Alle 7 sind in der Struktur plus [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (Die Benennung ist etwas anders, die Adressen sind gleich.)

Dann sind die Hardware cache events in Strukturen wie (in derselben Datei):

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

- Was sollte für Sandbrücke sein?

Eine davon - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]ist gefüllt mit SNB_DMND_WRITE|SNB_L3_ACCESS, wo aus den obigen Defs:

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

Das sollte gleich sein 0x00010102, aber ich weiß nicht, wie ich es mit einer Tabelle überprüfen soll.

Und dies gibt eine Vorstellung davon, wie es verwendet wird in 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));
$

Die memcpys sind erledigt in __init int intel_pmu_init(void) {... case:...}.

Nur attr->config1ist ein bisschen seltsam. Aber es ist da, in perf_event_attr(gleiche linux-source-3.13.0/include/uapi/linux/perf_event.hDatei):

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

Sie werden im Kernelsystem perf_eventsmit Aufrufen von int perf_pmu_register(struct pmu *pmu, const char *name, int type)(definiert in linux-source-3.13.0/kernel/events/core.c:) registriert :

  • static int __init init_hw_perf_events(void)(Datei arch/x86/kernel/cpu/perf_event.c) mit Anrufperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

  • static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)(Datei arch/x86/kernel/cpu/perf_event_intel_uncore.cgibt es auch arch/x86/kernel/cpu/perf_event_amd_uncore.c) mit Anrufret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

Schließlich kommen alle Ereignisse von der Hardware und alles ist in Ordnung. Aber hier könnte man bemerken: Warum haben wir LLC-loadsin perf listund nicht ubox1 LLC-loads, da dies HW-Ereignisse sind und sie tatsächlich von uboxes kommen?

Das ist eine Sache des perfDienstprogramms und seiner perf_evselStruktur: Wenn Sie ein HW-Ereignis von Ihnen anfordern perf, definieren Sie das Ereignis, von welchen Prozessoren Sie es möchten (Standard ist alles), und es richtet das perf_evselmit dem angeforderten Ereignis und den angeforderten Prozessoren ein, dann bei Aggregation summiert die Zähler aller Prozessoren in perf_evsel(oder führt andere Statistiken mit ihnen durch).

Man kann es sehen in 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;
}

(Für das Dienstprogramm ist perfein "einzelner Zähler" also nicht einmal eine perf_event_attrallgemeine Form, die sowohl für SW- als auch für HW-Ereignisse geeignet ist. Es ist ein Ereignis Ihrer Abfrage. Dieselben Ereignisse können von verschiedenen Geräten stammen und werden aggregiert .)

Auch ein Hinweis: struct perf_evselenthält nur 1 struct perf_evevent_attr, hat aber auch ein Feld struct perf_evsel *leader;- es ist verschachtelt. Es gibt eine Funktion von "(hierarchischen) Gruppen von Ereignissen" perf_events, bei der Sie eine Reihe von Zählern zusammen versenden können, damit sie miteinander verglichen werden können und so weiter. Nicht sicher , wie es funktioniert mit unabhängigen Ereignissen aus kernel, core, ubox. Aber diese Verschachtelung perf_evselist es. Und auf diese Weise wird höchstwahrscheinlich perfeine Abfrage mehrerer Ereignisse zusammen verwaltet.

xealits
quelle