O que são os eventos do PMU do Kernel na lista perf_events?

11

Procurando o que se pode monitorar perf_eventsno Linux, não consigo encontrar o que Kernel PMU eventsão? Ou seja, com perf version 3.13.11-ckt39os perf listeventos de shows como:

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

No geral, existem:

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

e eu gostaria de entender o que eles são, de onde eles vêm. Eu tenho algum tipo de explicação para todos, mas Kernel PMU eventitem.

No tutorial wiki do perf e na página de Brendan Gregg, entendi:

  • Tracepointssão as mais claras - são macros na fonte do kernel, que são um ponto de análise para monitoramento, foram introduzidas no ftraceprojeto e agora são usadas por todos
  • Software são os contadores de baixo nível do kernel e algumas estruturas de dados internas (portanto, são diferentes dos pontos de rastreamento)
  • Hardware eventsão alguns eventos muito básicos da CPU, encontrados em todas as arquiteturas e de alguma forma facilmente acessados ​​pelo kernel
  • Hardware cache eventsão apelidos para Raw hardware event descriptor- funciona da seguinte maneira

    como eu entendi, Raw hardware event descriptorexistem mais eventos (micro?) específicos da arquitetura do que Hardware eventos eventos vêm da PMU (Processor Monitoring Unit) ou outros recursos específicos de um determinado processador; portanto, eles estão disponíveis apenas em algumas micro-arquiteturas (digamos " arquitetura "significa" x86_64 "e todo o restante dos detalhes de implementação são" microarquitetura "); e eles são acessíveis para instrumentação através desses descritores estranhos

    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)
    

    - esses descritores, para quais eventos eles apontam e assim por diante, podem ser encontrados nos manuais do processador ( eventos da PMU no perf wiki );

    mas então, quando as pessoas sabem que há algum evento útil em um determinado processador, atribuem um apelido a ele e o conectam ao linux Hardware cache eventpara facilitar o acesso

    - corrija-me se estiver errado (estranhamente todos Hardware cache eventsão sobre something-loadsou something-misses- muito parecido com o cache do processador real)

  • agora o Hardware breakpoint

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

    é um recurso de hardware, que provavelmente é comum à maioria das arquiteturas modernas, e funciona como um ponto de interrupção em um depurador? (provavelmente é googlable de qualquer maneira)

  • finalmente, Kernel PMU eventnão consigo pesquisar no google;

    ele também não aparece na lista de eventos da página de perf de Brendan , então é novo?

    Talvez sejam apenas apelidos para eventos de hardware especificamente da PMU? (Para facilitar o acesso, há uma seção separada na lista de eventos, além do apelido.) De fato, talvez Hardware cache eventshaja apelidos para eventos de hardware do cache da CPU e Kernel PMU eventapelidos para eventos da PMU? (Por que não chamá-lo Hardware PMU evententão? ..) Poderia ser apenas um novo esquema de nomenclatura - os apelidos para eventos de hardware foram seccionados?

    E esses eventos se referem a coisas como cpu/mem-stores/, além disso, já que alguns eventos da versão linux receberam descrições /sys/devices/e:

    # 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é para ftracee pontos de rastreamento, outros diretórios correspondem exatamente ao que perf listmostra como Kernel PMU event.

Alguém poderia me indicar uma boa explicação / documentação do que são Kernel PMU eventsou /sys/..events/sistemas? Além disso, há /sys/..events/algum novo esforço para sistematizar eventos de hardware ou algo parecido? (Então, a PMU do Kernel é como "a Unidade de Monitoramento de Desempenho do Kernel".)

PS

Para dar um melhor contexto, prazo não-privilegiada de perf list(tracepoints não são mostrados, mas todos 1,374 deles estão lá) com listagens completas de Kernel PMU events e Hardware cache events e outros ignorado:

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

Respostas:

11

Googling and ack-ing acabou! Eu tenho uma resposta.

Mas, primeiro, deixe-me esclarecer um pouco mais o objetivo da pergunta: quero distinguir claramente processos independentes no sistema e seus contadores de desempenho. Por exemplo, um núcleo de um processador, um dispositivo não essencial (aprendido sobre isso recentemente), um kernel ou aplicativo de usuário no processador, um barramento (= controlador de barramento), um disco rígido são todos processos independentes, não são sincronizados por um relógio . E hoje em dia provavelmente todos eles têm algum PMC (Process Monitoring Counter). Eu gostaria de entender de quais processos vêm os contadores. (Também é útil no Google: o "vendedor" de uma coisa zera melhor.)

Além disso, o equipamento utilizado para a pesquisa: Ubuntu 14.04, linux 3.13.0-103-generic, processador Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz(a partir /proc/cpuinfo, tem 2 núcleos físicos e 4 Virtual - a matéria física aqui).

Terminologia, coisas que a pergunta envolve

Da Intel:

  • processador é um coredispositivo (é 1 dispositivo / processo) e um monte de uncoredispositivos , coreé o que executa o programa (relógio, ALU, registros etc.), uncoresão dispositivos colocados no molde, próximos ao processador para velocidade e baixa latência (a verdadeira razão é "porque o fabricante pode fazer isso"); como eu entendi, é basicamente o Northbridge, como na placa-mãe do PC, além de caches; e a AMD realmente chama esses dispositivos de NorthBridge instead ofuncore`;

  • ubox que aparece na minha sysfs

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

    - é um uncoredispositivo que gerencia o cache de último nível (LLC, o último antes de atingir a RAM); Eu tenho 2 núcleos, portanto 2 LLC e 2 ubox;

  • A Unidade de Monitoramento do Processador (PMU) é um dispositivo separado que monitora as operações de um processador e as registra no Contador de Monitoramento do Processador (PMC) (conta falhas de cache, ciclos do processador etc.); eles existem em coree uncoredispositivos; os coreones são acessados com rdpmcinstrução (leia PMC); o uncore, uma vez que esses dispositivos dependem do processador atual disponível, são acessados ​​via MSR (Model Specific Registers) via rdmsr(naturalmente);

    aparentemente, o fluxo de trabalho com eles é feito por meio de pares de registradores - 1 registrador define quais eventos o contador conta; 2 registrador é o valor no contador; o contador pode ser configurado para incrementar após vários eventos, não apenas 1; + existem algumas interrupções / aviso de transbordamento nesses contadores;

  • mais pode-se encontrar no "Manual do desenvolvedor de software IA-32, Vol 3B", capítulo 18 "MONITORAMENTO DE DESEMPENHO";

    além disso, o formato do MSR concretamente para esses uncorePMCs para a versão "Architectural Performance Monitoring Version 1" (há versões 1-4 no manual, não sei qual é o meu processador) está descrito na "Figura 18-1. Layout dos MSRs IA32_PERFEVTSELx "(página 18-3 na mina) e na seção" 18.2.1.2 Eventos de desempenho arquitetônicos predefinidos "com" Tabela 18-1. eventos que aparecem como Hardware eventem perf list.

Do kernel do linux:

  • O kernel possui um sistema (abstração / camada) para gerenciar contadores de desempenho de diferentes origens, tanto de software (do kernel) quanto de hardware, descrito em linux-source-3.13.0/tools/perf/design.txt; um evento neste sistema é definido como struct perf_event_attr(arquivo linux-source-3.13.0/include/uapi/linux/perf_event.h), cuja parte principal é provavelmente o __u64 configcampo - ele pode conter uma definição de evento específica da CPU (a palavra de 64 bits no formato descrito nas figuras da Intel) ou um evento do kernel

    O MSB da palavra de configuração significa se o restante contém [evento bruto da CPU ou do kernel]

    o evento do kernel definido com 7 bits para o tipo e 56 para o identificador do evento, que são enum-s no código e, no meu caso, são:

    $ 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é meu apelido para ack-grep, que é o nome ackdo Debian; e acké incrível);

    no código fonte do kernel pode-se ver operações como "registrar todas as PMUs descobertas no sistema" e tipos de estrutura struct pmu, que são passados ​​para algo como int perf_pmu_register(struct pmu *pmu, const char *name, int type)- assim, pode-se chamar esse sistema de "PMU do kernel", que seria uma agregação de todas as PMUs no sistema; mas esse nome poderia ser interpretado como sistema de monitoramento das operações do kernel, o que seria enganoso;

    vamos chamar esse subsistema perf_eventspara maior clareza;

  • como qualquer subsistema de kernel, esse subsistema pode ser exportado para sysfs(que é feito para exportar subsistemas de kernel para uso das pessoas); e é isso que são esses eventsdiretórios no meu /sys/- o perf_eventssubsistema exportado (partes de?) ;

  • Além disso, o utilitário de espaço do usuário perf(incorporado ao linux) ainda é um programa separado e possui suas próprias abstrações; ele representa um evento solicitado para monitoramento pelo usuário como perf_evsel(arquivos linux-source-3.13.0/tools/perf/util/evsel.{h,c}) - essa estrutura tem um campo struct perf_event_attr attr;, mas também um campo como struct cpu_map *cpus;o perfutilitário atribui um evento a todas as CPUs ou a determinadas unidades.

Responda

  1. De fato, Hardware cache eventsão "atalhos" para os eventos dos dispositivos de cache ( uboxdos dispositivos da Intel uncore), que são específicos do processador e podem ser acessados ​​através do protocolo Raw hardware event descriptor. E Hardware eventsão mais estáveis ​​na arquitetura, que, pelo que entendi, nomeiam os eventos do coredispositivo. Não há outros "atalhos" no meu kernel 3.13para alguns outros uncoreeventos e contadores. Todo o resto - Softwaree Tracepoints- são eventos do kernel.

    Pergunto-me se o core's Hardware events são acessados através do mesmo Raw hardware event descriptorprotocolo. Eles podem não funcionar - já que o contador / PMU fica aceso core, talvez ele seja acessado de maneira diferente. Por exemplo, com essa rdpmuinstrução, em vez de rdmsr, que acessa uncore. Mas isso não é importante.

  2. Kernel PMU eventsão apenas os eventos que são exportados para sysfs. Não sei como isso é feito (automaticamente pelo kernel todos os PMCs descobertos no sistema, ou apenas algo codificado, e se eu adicionar um kprobe- ele é exportado? Etc). Mas o ponto principal é que esses são os mesmos eventos Hardware eventdo perf_eventsistema interno .

    E eu não sei o que aqueles

    $ ls /sys/devices/uncore_cbox_0/events
    clockticks
    

    estamos.

Detalhes sobre Kernel PMU event

A pesquisa no código leva a:

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

- o que acontece na função

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

e perf_pmu__scanestá no mesmo arquivo:

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

- que também está no mesmo arquivo:

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

É isso aí.

Detalhes sobre Hardware eventeHardware cache event

Aparentemente, o Hardware eventresultado é o que a Intel chama de "Eventos de desempenho arquitetônico predefinidos", 18.2.1.2 no Manual do desenvolvedor de software IA-32, Vol 3B. E "18.1 VISÃO GERAL DO MONITORAMENTO DE DESEMPENHO" do manual descreve-os como:

A segunda classe de recursos de monitoramento de desempenho é chamada de monitoramento de desempenho arquitetural. Esta classe suporta os mesmos usos de amostragem de eventos baseados em contagem e interrupção, com um conjunto menor de eventos disponíveis. O comportamento visível dos eventos de desempenho arquitetural é consistente nas implementações do processador. A disponibilidade dos recursos de monitoramento de desempenho arquitetural é enumerada usando o CPUID.0AH. Esses eventos são discutidos na Seção 18.2.

- o outro tipo é:

Começando pelos processadores Intel Core Solo e Intel Core Duo, existem duas classes de capacidade de monitoramento de desempenho. A primeira classe suporta eventos para monitorar o desempenho usando o uso de amostragem de eventos baseada em contagem ou interrupção. Esses eventos não são arquitetônicos e variam de um modelo de processador para outro ...

E esses eventos são de fato apenas links para eventos de hardware "brutos" subjacentes, que podem ser acessados ​​via perfutilitário como Raw hardware event descriptor.

Para verificar isso, veja 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,
    ...
}

- e exatamente 0x412eé encontrado em "Tabela 18-1. Codificações de UMask e de seleção de eventos para eventos de desempenho arquitetônico predefinidos" para "LLC Misses":

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

- Hé para hexadecimal. Todos os 7 estão na estrutura, mais [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *. (A nomeação é um pouco diferente, os endereços são os mesmos.)

Então, os Hardware cache events estão em estruturas como (no mesmo arquivo):

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

- qual deve ser a ponte de areia?

Um deles - snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]é preenchido com SNB_DMND_WRITE|SNB_L3_ACCESS, de onde, nas def-s acima:

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

que deve ser igual a 0x00010102, mas não sei como verificar com alguma tabela.

E isso dá uma idéia de como é usado 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));
$

Os memcpys são feitas em __init int intel_pmu_init(void) {... case:...}.

attr->config1é um pouco estranho. Mas está lá, no perf_event_attrmesmo linux-source-3.13.0/include/uapi/linux/perf_event.harquivo:

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

Eles são registrados no perf_eventssistema do kernel com chamadas para int perf_pmu_register(struct pmu *pmu, const char *name, int type)(definidas em linux-source-3.13.0/kernel/events/core.c:):

  • static int __init init_hw_perf_events(void)(arquivo arch/x86/kernel/cpu/perf_event.c) com chamadaperf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

  • static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)(arquivo arch/x86/kernel/cpu/perf_event_intel_uncore.c, também existem arch/x86/kernel/cpu/perf_event_amd_uncore.c) com chamadaret = perf_pmu_register(&pmu->pmu, pmu->name, -1);

Então, finalmente, todos os eventos vêm de hardware e está tudo bem. Mas aqui pode-se notar: por que temos LLC-loadsem perf liste não ubox1 LLC-loads, uma vez que estes são eventos de HW e eles actualy vêm de uboxes?

Isso é coisa do perfutilitário e de sua perf_evselestrutura: quando você solicita um evento HW, perfdefine o evento de que processadores você deseja (o padrão é tudo) e configura perf_evselo evento e os processadores solicitados; em seguida, a agregação é soma os contadores de todos os processadores perf_evsel(ou faz outras estatísticas com eles).

Pode-se ver em 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;
}

(Portanto, para o utilitário, perfum "contador único" não é nem um perf_event_attr, que é uma forma geral, ajustando eventos SW e HW, é um evento da sua consulta - os mesmos eventos podem vir de dispositivos diferentes e são agregados .)

Também um aviso: struct perf_evselcontém apenas 1 struct perf_evevent_attr, mas também possui um campo struct perf_evsel *leader;- está aninhado. Há um recurso de "grupos (hierárquicos) de eventos" em perf_events, quando você pode despachar vários contadores juntos, para que eles possam ser comparados entre si e assim por diante. Não tenho certeza como ele trabalha com eventos independentes de kernel, core, ubox. Mas esse aninhamento perf_evselé isso. E, provavelmente, é assim que perfgerencia uma consulta de vários eventos juntos.

xealits
fonte