Como o kernel atribui ids de cpu a núcleos físicos?

3

Pode-se encontrar muita informação sobre como inspecionar o layout de núcleos físicos em um sistema Linux em execução, mas estou querendo saber como os núcleos físicos são atribuídos a um id de CPU em primeiro lugar.

Depois de experimentar em algumas máquinas, parece-me que a atribuição é determinista (ou seja, a inicialização a partir do mesmo hardware resultará na mesma atribuição de IDs da CPU ao núcleo de processamento físico). Além disso, parece-me que a atribuição funciona de alguma forma "round-robin", de tal forma que dois núcleos com números próximos estão fisicamente distantes um do outro. Por exemplo, em um servidor em que estou trabalhando (2 soquetes x 8 cpus x 2 hyperthreading, x86_64): cpu0 está no soquete 0 , cpu1 está no soquete 1 e, em seguida, cpu2 está novamente no soquete 0 mas está em um núcleo físico diferente de cpu0 ; ... continua assim até cpu15 , então cpu16 é hyperthreaded no mesmo núcleo físico que cpu0 .

Se isso for deliberado como parece, você sabe de algum lugar que eu possa encontrar esse comportamento documentado? Qual é a razão por trás disso?

Eu apreciaria especialmente qualquer referência à documentação ou post de lkml, mas até mesmo um ponteiro para o lugar certo nas fontes poderia ser útil.

    
por Davide 03.05.2016 / 11:57

1 resposta

1

É dificilmente documentado e depende em grande parte de uma plataforma. Para x86, o próximo ID disponível é atribuído à CPU na função generic_processor_info()

Portanto, para x86, os IDs da CPU dependem da ordem em que chamaríamos essa função. Ele é chamado quando o APIC (controlador de interrupção) é inicializado, enquanto as configurações de APIC são obtidas da tabela ACPI MADT e as tabelas da ACPI são fornecidas pelo BIOS.

Você pode tentar decodificá-las usando as ferramentas da ACPI ( acpica-tools package no CentOS):

# acpidump > acpi.dat
# acpixtract -a acpi.dat
# iasl -d apic.dat
...
# cat apic.dsl | awk -F: '/Subtable Type/ { st = $2 }
                          /Processor ID/ { id = $2 }
                          /Processor Enabled/ { print id, $2, st } '
    
por 05.05.2016 / 00:13