CPU 토폴로지 (CPU Topology)

CPU 토폴로지를 커널 스케줄러 관점에서 심층적으로 다룹니다. AMD Chiplet(CCD/CCX), Intel Hybrid(P-core/E-core), ARM DynamIQ/DSU 구조가 커널 topology 탐지와 sched_domain 계층에 반영되는 과정을 분석하고, 비대칭 용량 스케줄링과 NUMA 연계 배치, 관측 도구를 활용한 성능 진단 절차까지 종합적으로 설명합니다.

현대 프로세서는 단순한 "코어 수 × 스레드 수" 이상의 복잡한 계층 구조를 가집니다. AMD의 칩렛(Chiplet), Intel의 타일(Tile)/하이브리드, ARM의 DynamIQ 등 각 아키텍처는 고유한 토폴로지를 형성하며, 리눅스 커널은 이를 정확히 인식하고 스케줄링·메모리 배치에 반영해야 최적 성능을 달성할 수 있습니다.

관련 페이지: NUMA 노드 수준의 메모리 토폴로지는 NUMA 심화 페이지를, CPUID 명령어의 세부 동작은 CPUID — CPUID 기반 토폴로지 탐지를, 스케줄러의 전반적인 동작은 프로세스 관리 페이지를 참조하세요.
관련 표준: Intel SDM (CPUID, APIC 토폴로지), AMD APM (토폴로지 열거), ARM DynamIQ (클러스터 구조) — CPU 토폴로지 탐색에 사용되는 프로세서 아키텍처 규격입니다. 종합 목록은 참고자료 — 표준 & 규격 섹션을 참고하세요.
전제 조건: CPU 토폴로지어셈블리 문서를 먼저 읽으세요. CPU 구조 주제는 하드웨어 계층과 명령어 수준 제어가 맞물리므로, 코어/캐시/레지스터 경계를 먼저 정리해야 합니다.
일상 비유: CPU 토폴로지는 회사 조직도와 같습니다. Socket(회사) 안에 Die/CCD(부서)가 있고, 그 안에 Core(팀)가 있으며, SMT 덕분에 한 팀이 두 가지 일을 동시에 처리합니다. EAS는 "이 업무는 빠른 직원(big 코어)에게, 저 업무는 경제적인 직원(LITTLE 코어)에게" 배분하는 관리자입니다. CPU 격리는 특정 직원을 중요 프로젝트 전담으로 지정하는 것과 같습니다.

핵심 요약

  • Socket → Die → Core → Thread — CPU의 물리적 계층 구조입니다.
  • SMT(Hyper-Threading) — 하나의 코어가 두 개 이상의 논리 CPU로 동작합니다.
  • CPUID — 프로세서가 자신의 토폴로지 정보를 소프트웨어에 알려주는 명령어입니다.
  • sched_domain — 커널 스케줄러가 토폴로지를 인식하여 부하를 분산하는 계층 구조입니다.
  • lscpu / sysfslscpu 명령어와 /sys/devices/system/cpu/로 토폴로지를 확인합니다.
  • EAS (Energy-Aware Scheduling) — 이종 코어 시스템에서 성능과 전력의 균형을 맞추는 스케줄러 알고리즘입니다.
  • CPU 격리 (isolcpus) — 특정 코어를 OS 스케줄러에서 분리하여 실시간/레이턴시 중요 태스크 전용으로 사용합니다.
  • SMT 보안 — Spectre V2, L1TF 등 투기적 실행 취약점은 SMT의 자원 공유 구조와 직접 연관됩니다.

단계별 이해

  1. 토폴로지 확인lscpu를 실행하여 소켓 수, 코어 수, 스레드 수를 확인합니다.

    /sys/devices/system/cpu/cpu0/topology/에서 상세 정보를 볼 수 있습니다.

  2. 계층 이해 — 같은 코어의 SMT 스레드는 L1 캐시를, 같은 다이의 코어는 L3 캐시를 공유합니다.

    이 공유 관계가 스케줄링과 성능에 직접적인 영향을 줍니다.

  3. 스케줄링 도메인 — 커널은 토폴로지를 기반으로 SMT → Core → LLC → NUMA 순의 스케줄링 도메인을 구성합니다.

    부하 균형 시 가까운 도메인부터 먼 도메인 순으로 태스크를 이동합니다.

  4. 성능 최적화taskset이나 cgroup의 cpuset으로 프로세스를 특정 코어에 바인딩할 수 있습니다.

    캐시 공유 관계를 고려한 바인딩이 성능 최적화의 핵심입니다.

  5. 전력 관리 — EAS는 에너지 모델(Energy Model)을 사용해 태스크를 가장 전력 효율적인 코어에 배치합니다.

    /sys/kernel/debug/energy_model/로 EM 등록 상태를 확인할 수 있습니다.

  6. 보안과 격리 — SMT 비활성화(nosmt)나 CPU 격리(isolcpus)로 사이드채널 공격 위험을 줄입니다.

    /sys/devices/system/cpu/vulnerabilities/에서 취약점 완화 상태를 확인합니다.

AMD Chiplet 아키텍처

AMD는 Zen 아키텍처부터 칩렛(Chiplet) 설계를 도입하여, 하나의 패키지에 여러 개의 소형 다이를 조합하는 방식으로 프로세서를 구성합니다. 이 접근법은 제조 수율 향상, 유연한 코어 수 확장, 비용 효율성이라는 장점을 제공합니다.

CCX (Core CompleX)

CCX는 AMD 프로세서의 기본 컴퓨팅 단위로, 일정 수의 코어가 L3 캐시를 공유하는 클러스터입니다.

세대CCX 구성L3 캐시/CCX비고
Zen1 / Zen+4코어/CCX8MB2 CCX = 1 CCD
Zen24코어/CCX16MB2 CCX = 1 CCD, L3 2배 증가
Zen38코어/CCX32MB1 CCX = 1 CCD, 통합 L3
Zen48코어/CCX32MB5nm, AVX-512
Zen58코어/CCX32MB프론트엔드 2-wide 디코드

CCX 내부의 코어들은 L3 캐시를 공유하므로 inter-core 지연이 매우 낮습니다. 커널의 스케줄링 도메인에서 MC(Multi-Core) 레벨에 해당합니다.

CCD (Core Chiplet Die)

CCD는 코어가 집적된 물리적 다이(die)입니다.

Zen2 CCD 내부 구조 CCD (Die) CCX 0 Core 0 Core 1 Core 2 Core 3 L3 16MB IF CCX 1 Core 4 Core 5 Core 6 Core 7 L3 16MB Infinity Fabric → IOD Zen3+ CCD 내부 구조 (통합) CCD = CCX (Die) — 8코어 통합, L3 전체 공유 Core 0 Core 1 Core 2 Core 3 Core 4 Core 5 Core 6 Core 7 L3 32MB (8코어 전체 공유) Infinity Fabric → IOD

IOD (I/O Die)

IOD는 I/O 기능을 전담하는 별도의 다이입니다. Zen2부터 컴퓨팅 다이(CCD)와 I/O 다이(IOD)를 물리적으로 분리하여, 각각 최적의 공정을 적용합니다.

IOD가 담당하는 주요 기능:

/* 커널에서 AMD IOD 토폴로지 확인 (dmesg) */
// [    0.123456] node 0 deferred pages: init 2097152
// AMD EPYC 9654 (Genoa): 12 UMC channels, 128 PCIe Gen5 lanes

/* arch/x86/kernel/cpu/amd.c - 토폴로지 파싱 */
static void amd_get_topology(struct cpuinfo_x86 *c)
{
    int cpu = c->cpu_index;

    /* CPUID Fn8000_001E: Node/Core/Thread 토폴로지 */
    if (c->extended_cpuid_level >= 0x8000001e) {
        u32 eax, ebx, ecx, edx;
        cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);

        c->cpu_core_id = eax;                     /* Compute Unit ID */
        c->cpu_die_id  = ecx & 0xff;              /* Node(CCD) ID */
        c->threads_per_core = ((ebx >> 8) & 0xff) + 1;
    }
}

Infinity Fabric

Infinity Fabric(IF)는 AMD의 온-다이/온-패키지/인터-소켓 인터커넥트입니다. Scalable Data Fabric(SDF)과 Scalable Control Fabric(SCF)으로 구성됩니다.

통신 경로경유대략적 지연대역폭
intra-CCX (코어 간)L3 직접~10-15nsL3 대역폭
inter-CCX, same CCD (Zen1/2)IF on-die~25-40nsIF 대역폭
inter-CCD (same socket)IF → IOD → IF~50-80nsIF 대역폭
inter-socketxGMI~120-180nsxGMI 대역폭
FCLK / MCLK 관계: Infinity Fabric 클럭(FCLK)과 메모리 클럭(MCLK)은 밀접하게 연결됩니다. Zen2/3에서 FCLK:MCLK = 1:1 동기 모드가 최적이며, 비동기(2:1) 시 IF 지연이 증가합니다. Zen4부터 FCLK 최대치가 높아져 DDR5 고속 메모리와의 동기 범위가 확대되었습니다.

NPS (Nodes Per Socket)

AMD EPYC 프로세서는 NPS(Nodes Per Socket) BIOS 설정으로 단일 소켓 내부를 여러 NUMA 노드로 분할합니다.

모드NUMA 노드/소켓CCD→메모리 매핑적합한 워크로드
NPS11모든 CCD → 전체 메모리 채널범용, 대용량 메모리 풀
NPS22CCD 절반씩 → 메모리 채널 절반VM 2개 분할
NPS44CCD 1/4씩 → 메모리 채널 1/4HPC, 지연 최소화
# NPS 모드 확인 (NUMA 노드 수로 추정)
$ numactl --hardware
available: 4 nodes (0-3)    # NPS4 모드
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 64169 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 64256 MB
...
node distances:
node   0   1   2   3
  0:  10  12  12  12
  1:  12  10  12  12
  2:  12  12  10  12
  3:  12  12  12  10
NPS와 NUMA 정책: NPS 모드별 NUMA 메모리 정책(mbind, set_mempolicy)과 Automatic NUMA Balancing에 대한 자세한 내용은 NUMA 심화 페이지를 참조하세요.

Zen 세대별 진화

세대공정CCX/CCD최대 CCDL3/CCXIF 세대메모리
Zen114nm2 CCX(4c)/CCD4 (EPYC 7001)8MBIF 1.0DDR4-2666
Zen27nm CCD / 14nm IOD2 CCX(4c)/CCD8 (EPYC 7002)16MBIF 2.0DDR4-3200
Zen37nm1 CCX(8c)=CCD8 (EPYC 7003)32MBIF 3.0DDR4-3200
Zen45nm CCD / 6nm IOD1 CCX(8c)=CCD12 (EPYC 9004)32MBIF 4.0DDR5-4800
Zen54nm/3nm1 CCX(8c)=CCD16 (EPYC 9005)32MBIF 5.0DDR5-6000

EPYC / Ryzen / Threadripper 비교

제품군소켓최대 CCD최대 코어메모리 채널PCIe 레인NPS 지원
EPYC 9004 (Genoa)SP5129612×DDR5128 Gen5NPS1/2/4
EPYC 9005 (Turin)SP51612812×DDR5128 Gen5NPS1/2/4
Threadripper 7000sTR58644×DDR548 Gen5NPS1
Ryzen 9000 (Granite Ridge)AM52162×DDR528 Gen5N/A
Ryzen 9000 (Strix Point)FP81 (모놀리식)12LPDDR5X내장N/A
AMD EPYC 칩렛 아키텍처 (Zen4/Genoa 기준) CCD 0 C0 C1 C2 C3 C4 C5 C6 C7 L3 32MB CCD 1 C0 C1 C2 C3 C4 C5 C6 C7 L3 32MB CCD 2 8C / L3 32MB CCD 3 8C / L3 32MB IF IF IF IF IOD (I/O Die) IF Switch UMC (DDR5) PCIe Gen5 xGMI PSP (보안) CXL 컨트롤러 CCD 4 8C / L3 32MB CCD 5 8C / L3 32MB CCD 6 8C / L3 32MB CCD 7 8C / L3 32MB → Socket 1 DDR5 (12ch)

Intel 아키텍처

2.1 Tile 아키텍처

Intel은 서버 프로세서(Sapphire Rapids, Granite Rapids)에서 EMIB(Embedded Multi-die Interconnect Bridge)를 사용한 타일 기반 설계를 도입했습니다.

클라이언트 프로세서에서도 Meteor Lake부터 분리형 타일 설계(Foveros 3D 패키징)가 도입되어, Compute/SoC/GFX/IOE 타일로 구성됩니다(자세한 내용은 2.12 분리형 SoC 설계 참조).

# SNC 모드 확인 (Sapphire Rapids, SNC4)
$ lscpu | grep -i numa
NUMA node(s):          4
NUMA node0 CPU(s):     0-14,60-74
NUMA node1 CPU(s):     15-29,75-89
NUMA node2 CPU(s):     30-44,90-104
NUMA node3 CPU(s):     45-59,105-119

2.2 P-core / E-core 하이브리드

Alder Lake(12세대)부터 클라이언트 프로세서에 하이브리드 아키텍처를 도입했습니다. 이는 단일 다이(또는 패키지)에 고성능 P-core(Performance)와 고효율 E-core(Efficient)를 혼합 배치하는 설계입니다.

하이브리드 도입 배경:

특성P-core (Performance)E-core (Efficient)
마이크로아키텍처Golden Cove / Raptor Cove / Lion CoveGracemont / Crestmont / Skymont
SMT지원 (2 스레드/코어)미지원 (1 스레드/코어)
L2 캐시1.25~3MB/코어 (개별)2~4MB/4코어 클러스터 (공유)
ISA 차이AVX-512 (세대별 상이)AVX-512 미지원
IPC높음P-core 대비 ~70-85% (세대별 향상)
전력 효율성능 우선와트당 성능 우수
다이 면적크다 (~4mm² @Intel 7)작다 (~1mm² @Intel 7)

E-core 클러스터 토폴로지: E-core 4개가 하나의 클러스터(Cluster)를 이루며, 클러스터 내 L2 캐시를 공유합니다. 커널에서는 이 클러스터를 CL(Cluster) 스케줄링 도메인 레벨로 인식합니다. 같은 클러스터 내 E-core 간 데이터 교환은 L2를 통해 이루어지므로 지연이 매우 낮지만, 다른 클러스터의 E-core나 P-core와의 통신은 링 버스/LLC를 경유합니다.

2.3 P-core 마이크로아키텍처

P-core는 Intel의 고성능 마이크로아키텍처 계열로, 넓은 프론트엔드와 깊은 OoO(Out-of-Order) 파이프라인을 특징으로 합니다.

마이크로아키텍처세대디코드 폭ROB 크기실행 포트L2/코어주요 특징
Golden CoveAlder Lake (12th)6-wide512121.25MB최초 하이브리드 P-core, 10-wide alloc
Raptor CoveRaptor Lake (13th)6-wide512122MBL2 확대, 클럭 개선 (최대 6.0GHz)
Redwood CoveMeteor Lake (Core Ultra 1)6-wide512122MB전력 게이팅 향상, Compute tile 분리
Lion CoveArrow/Lunar Lake (Core Ultra 2)8-wide576122.5~3MB디코드 폭 확대, AVX-512 복원(P-core 한정)

Golden Cove (Alder Lake) — P-core의 첫 하이브리드 설계입니다. 6-wide 디코드, 512-entry ROB(Reorder Buffer), 12개 실행 포트를 갖추어 이전 세대(Cypress Cove) 대비 ~19% IPC 향상을 달성했습니다. L2 캐시는 코어당 1.25MB이며, 프리페칭 개선과 브랜치 예측기 확장이 적용되었습니다.

Raptor Cove (Raptor Lake) — Golden Cove의 파이프라인을 유지하면서 L2를 2MB로 확대하고, 클럭 스케일링을 개선하여 최대 부스트 6.0GHz를 달성했습니다. 캐시 프리페칭 개선으로 메모리 집약적 워크로드에서 추가 IPC 향상이 있습니다.

Redwood Cove (Meteor Lake) — 분리형 Compute tile(Intel 4 공정)에 탑재됩니다. 파이프라인은 Golden Cove와 유사하지만, 타일 단위 전력 게이팅으로 유휴 시 P-core 타일 전체를 전력 차단할 수 있어 배터리 수명이 크게 개선됩니다.

Lion Cove (Arrow Lake / Lunar Lake) — 디코드 폭을 8-wide로 확대하고 ROB를 576개로 늘렸습니다. 가장 주목할 변화는 P-core 한정으로 AVX-512를 복원한 것입니다. E-core에서는 여전히 AVX-512를 지원하지 않으므로, 커널은 ISA 비대칭성을 처리해야 합니다(2.9 ISA 호환성 참조).

2.4 E-core 마이크로아키텍처

E-core는 "느린 코어"가 아닌 "효율 코어"입니다. Skylake급 IPC를 달성하면서 훨씬 낮은 전력과 작은 다이 면적으로 동작하도록 설계되었습니다.

마이크로아키텍처세대디코드클러스터 구성L2/클러스터IPC (vs P-core)
GracemontAlder Lake / Raptor Lake2-wide × 2 파이프4코어/클러스터2MB (ADL) / 4MB (RPL)~70%
CrestmontMeteor Lake / Lunar Lake LP향상된 프론트엔드4코어/클러스터4MB~80-85%
SkymontArrow Lake / Lunar Lake추가 IPC 개선4코어/클러스터4MB~85%

Gracemont (Alder Lake/Raptor Lake) — 2개의 독립적인 2-wide 디코드 파이프를 사용하는 독특한 클러스터 구조입니다. SMT를 지원하지 않는 대신 코어 자체를 소형화하여, P-core 1개의 다이 면적에 E-core 4개를 집적합니다. 4코어가 하나의 클러스터를 이루어 L2 캐시를 공유하며, 이 공유 구조가 커널에서 CL(Cluster) 스케줄링 도메인을 형성합니다.

Crestmont (Meteor Lake) — 프론트엔드 분기 예측 개선과 백엔드 실행 유닛 확장으로 IPC가 P-core 대비 ~80-85% 수준으로 향상되었습니다. Meteor Lake SoC tile의 LP E-core(2.5절 참조)로도 사용되며, 이 경우 낮은 클럭(1~2GHz)으로 동작합니다.

Skymont (Arrow Lake / Lunar Lake) — 추가적인 IPC 개선으로 Gracemont 대비 최대 ~38% 향상을 달성했습니다. 벡터 처리 능력도 강화되어 256-bit SIMD 처리량이 증가했습니다.

효율 코어의 의미: E-core의 싱글 스레드 성능은 2~3세대 전 P-core(Skylake~Coffee Lake)에 필적합니다. "E-core = 느린 코어"가 아닌 "E-core = 작은 면적에서 충분한 성능"으로 이해해야 합니다. 4개 E-core 클러스터의 멀티스레드 처리량은 2개 P-core 수준이면서, 전력 소비는 절반 이하입니다.

2.5 LP E-core와 3계층 코어

Meteor Lake부터 SoC tile에 LP E-core(Low-Power Efficient core)가 추가되어, 프로세서가 3계층 코어 구조를 갖게 되었습니다.

계층코어 타입위치특성용도
1 (최고성능)P-coreCompute tile높은 클럭, 넓은 파이프라인게임, 컴파일, 싱글스레드 집약
2 (효율)E-coreCompute tile중간 클럭, 4코어 클러스터멀티스레드, 백그라운드
3 (초저전력)LP E-coreSoC tile1~2GHz, 2코어 구성경량 작업, 대기 시 유지

LP E-core의 특성:

커널 영향: 3계층 코어 구조에서 스케줄러는 추가적인 우선순위 레벨을 관리해야 합니다. ITMT(2.8절)에서 LP E-core는 가장 낮은 우선순위를 받으며, 스케줄링 도메인에서도 별도의 Module 레벨로 인식될 수 있습니다.

2.6 세대별 진화

세대공정P-coreE-coreLP EP수E수P-L2E-L2/CLL3메모리설계
Alder Lake (12th)Intel 7Golden CoveGracemont-881.25MB2MB30MBDDR5-4800모놀리식
Raptor Lake (13th)Intel 7Raptor CoveGracemont-8162MB4MB36MBDDR5-5600모놀리식
Meteor Lake (Ultra 1)Intel 4/N6/N5Redwood CoveCrestmontCrestmont682MB4MB12MBLPDDR5X분리형(Foveros)
Arrow Lake (Ultra 2)TSMC N3/N6Lion CoveSkymont-8163MB4MB36MBDDR5-5600분리형
Lunar Lake (Ultra 2)TSMC N3/N6Lion CoveSkymontCrestmont442.5MB4MB12MBLPDDR5X분리형
코어 수 표기: 위 표의 P수/E수는 해당 세대의 최대 구성(K/HX SKU) 기준입니다. 실제 SKU별로 P-core/E-core 수가 다르며, 일부 SKU에서는 E-core가 완전히 비활성화되기도 합니다.

2.7 코어 타입 탐지 — CPUID Leaf 0x1A

하이브리드 프로세서에서 커널은 각 논리 CPU가 P-core인지 E-core인지 식별해야 합니다. Intel은 CPUID Leaf 0x1A (Native Model ID Enumeration)를 통해 이 정보를 제공합니다.

EAX 비트필드의미
[31:24]Core Type0x20Atom (E-core)
[31:24]Core Type0x40Core (P-core)
[23:0]Native Model ID-마이크로아키텍처별 고유 ID
/* arch/x86/kernel/cpu/intel.c — 하이브리드 코어 타입 탐지 */
static void detect_hybrid_cpu(struct cpuinfo_x86 *c)
{
    u32 eax, ebx, ecx, edx;

    if (!cpu_has(c, X86_FEATURE_HYBRID_CPU))
        return;

    cpuid(0x1a, &eax, &ebx, &ecx, &edx);

    /* EAX[31:24] = Core Type
     * 0x20 = Intel Atom (E-core)
     * 0x40 = Intel Core (P-core) */
    c->topo.core_type = (eax >> 24) & 0xff;
    c->topo.native_model_id = eax & 0xffffff;
}

/* X86_FEATURE_HYBRID_CPU는 CPUID Leaf 7, ECX bit 15로 탐지
 * (CPUID.07H:EDX[15] = Hybrid 지원 여부) */

CPUID 0x1F V2 Extended Topology와의 연동: Leaf 0x1F에서 Module 레벨(level_type=3)을 통해 E-core 클러스터를 식별할 수 있습니다. 같은 Module에 속한 E-core들은 L2를 공유하며, 커널은 이를 CL 스케줄링 도메인으로 매핑합니다.

# 코어 타입 확인 (sysfs)
$ for cpu in /sys/devices/system/cpu/cpu*/topology; do
    if [ -f "$cpu/core_type" ]; then
        echo "$(basename $(dirname $cpu)): $(cat $cpu/core_type)"
    fi
  done
cpu0: 64    # 0x40 = P-core (Intel Core)
cpu1: 64
...
cpu16: 32   # 0x20 = E-core (Intel Atom)
cpu17: 32
...

2.8 ITMT 비대칭 스케줄링

ITMT(Intel Turbo Boost Max Technology 3.0)는 코어별 성능 차이를 커널 스케줄러에 반영하는 메커니즘입니다. 하이브리드 프로세서에서 P-core > E-core > LP E-core 우선순위를 설정하여 비대칭 스케줄링을 구현합니다.

/* arch/x86/kernel/itmt.c — ITMT 우선순위 설정 */

/* 코어별 성능 우선순위를 스케줄러에 등록 */
void sched_set_itmt_core_prio(int prio, int cpu)
{
    per_cpu(sched_core_priority, cpu) = prio;
}

/* ITMT 활성화 — sched_domain에 SD_ASYM_PACKING 플래그 설정 */
void sched_set_itmt_support(void)
{
    sysctl_sched_itmt_enabled = 1;
    rebuild_sched_domains();
}

/*
 * 동작 원리:
 * 1. intel_pstate 또는 HFI 드라이버가 각 코어의 성능 순위를 파악
 * 2. sched_set_itmt_core_prio()로 코어별 우선순위 설정
 *    예: P-core = 200, E-core = 100, LP E-core = 50
 * 3. SD_ASYM_PACKING이 설정된 도메인에서 스케줄러는
 *    높은 우선순위 코어를 먼저 채움
 * 4. 워크로드가 줄어들면 낮은 우선순위 코어에서 먼저 제거
 */

주요 커널 인터페이스:

# ITMT 활성 상태 확인
$ cat /proc/sys/kernel/sched_itmt_enabled
1

# 스케줄링 도메인에서 ASYM_PACKING 플래그 확인
$ cat /proc/sys/kernel/sched_domain/cpu0/domain0/flags
... SD_ASYM_PACKING ...

2.9 ISA 호환성

하이브리드 아키텍처의 핵심 과제 중 하나는 P-core와 E-core 간 ISA(Instruction Set Architecture) 차이입니다. 특히 AVX-512가 세대별로 달라지는 점이 커널과 사용자 공간 모두에 영향을 줍니다.

세대P-core AVX-512E-core AVX-512OS에 노출
Alder Lake (12th)하드웨어 존재미지원E-core 비활성 시 일부 SKU에서 사용 가능 (BIOS)
Raptor Lake (13th)퓨즈 차단미지원완전 비활성
Meteor Lake미지원미지원비활성
Arrow Lake / Lunar Lake복원 (지원)미지원P-core에서만 사용 가능

커널의 ISA 처리 원칙 — 최소 공통 분모:

기본적으로 커널은 모든 코어가 지원하는 ISA의 교집합만 사용자 공간에 노출합니다. E-core가 AVX-512를 지원하지 않으면, CPUID를 통해 OS에 AVX-512가 광고되지 않습니다. 따라서 Alder Lake~Meteor Lake에서는 AVX-512를 사용할 수 없습니다.

Arrow Lake+에서의 변화: Lion Cove P-core에서 AVX-512가 복원되었지만, Skymont E-core는 여전히 미지원입니다. Intel은 이 비대칭 ISA를 처리하기 위해:

ISA 비대칭성 주의: Arrow Lake 이후에서 AVX-512를 사용하려면 해당 스레드가 반드시 P-core에서 실행되어야 합니다. taskset이나 sched_setaffinity()로 P-core에 명시적으로 고정하지 않으면, 스케줄러가 E-core로 마이그레이션할 때 SIGILL이 발생할 수 있습니다. 커널 6.x에서 이를 자동 처리하는 패치가 진행 중이지만, 현재는 사용자 공간에서 주의가 필요합니다.

2.10 Intel Thread Director

Intel Thread Director(ITD)는 하드웨어 기반의 스레드 분류기로, 각 스레드의 명령어 mix를 실시간 분석하여 P-core/E-core 배치를 최적화합니다.

IPC 클래스 분류: Thread Director는 스레드가 실행하는 명령어 패턴을 모니터링하여 4개 IPC 클래스 중 하나를 할당합니다:

IPC 클래스명령어 특성권장 코어예시
Class 0범용 코드P-core 또는 E-core일반 애플리케이션
Class 1정수 연산 중심E-core 충분웹 브라우징, 스크립트
Class 2벡터/SIMD 연산P-core 선호미디어 인코딩
Class 3FP/AVX 집중P-core 강력 선호과학 계산, 게임 물리
/* HFI (Hardware Feedback Interface) 테이블 구조 */
struct hfi_cpu_data {
    u8  perf_cap;    /* 성능 능력: 0(최저)~255(최고) */
    u8  ee_cap;      /* 에너지 효율: 0(최저)~255(최고) */
};

/*
 * 커널 드라이버: drivers/thermal/intel/intel_hfi.c
 *
 * HFI 테이블은 MMIO 영역에 매핑되며, 인터럽트로 갱신 알림.
 * 갱신 주기: 약 ~100ms (워크로드 변화 시 동적 조절)
 *
 * 열 제한(thermal throttling) 시 perf_cap이 동적으로 감소:
 *   정상 → P-core perf_cap=255, E-core perf_cap=128
 *   열 제한 → P-core perf_cap=180, E-core perf_cap=100
 * 이를 통해 스케줄러가 열 상태에 따라 배치를 자동 조절
 */
static void intel_hfi_process_event(struct work_struct *work)
{
    struct hfi_instance *hfi = container_of(work, ...);
    /* HFI 테이블에서 각 CPU의 perf_cap/ee_cap 읽기 */
    raw_spin_lock_irq(&hfi->table_lock);
    memcpy(hfi->local_table, hfi->hw_table, hfi->table_size);
    raw_spin_unlock_irq(&hfi->table_lock);
    /* ITMT 우선순위 갱신 → 스케줄러에 용량 변경 알림 */
    sched_update_cpu_topology();
}

HFI → ITMT → 스케줄러 연동 흐름:

  1. Thread Director가 IPC 클래스를 계산하여 HFI 테이블에 기록
  2. HFI 인터럽트 → intel_hfi_process_event() → HFI 테이블 복사
  3. perf_cap/ee_cap 값을 ITMT 우선순위로 변환 → sched_set_itmt_core_prio()
  4. sched_update_cpu_topology() → 스케줄링 도메인 재구축
  5. CFS 스케줄러가 SD_ASYM_PACKING 플래그에 따라 높은 우선순위 코어에 태스크 배치

2.11 캐시 토폴로지

Intel의 LLC(Last-Level Cache)는 슬라이스 형태로 분산되어 있으며, 링 버스 또는 메시 인터커넥트로 연결됩니다.

캐시 심화: 캐시 연관도, 교체/쓰기 정책, 코히런시 프로토콜(MESI/MOESI/MESIF), TLB, 프리페칭, Intel RDT, false sharing 등의 자세한 내용은 CPU 캐시 심화 페이지를 참조하세요.

2.12 분리형 SoC 설계 — Meteor Lake+

Meteor Lake부터 Intel은 Foveros 3D 패키징을 사용하여 여러 타일을 하나의 패키지에 조합하는 분리형(disaggregated) 설계를 클라이언트 프로세서에 도입했습니다.

4-Tile 구조 (Meteor Lake):

  1. Compute tile (Intel 4): P-core(Redwood Cove) + E-core(Crestmont) + L3 캐시
  2. SoC tile (TSMC N6): LP E-core(Crestmont 2코어) + NPU(AI 엔진) + 미디어 엔진 + 디스플레이 엔진
  3. GFX tile (TSMC N5): Xe-LPG GPU (128 EU)
  4. IOE tile (TSMC N6): PCIe Gen5, Thunderbolt 4, USB 4, 기타 I/O

각 타일은 독립적인 FIVR(Fully Integrated Voltage Regulator)를 탑재하여 전압/주파수를 개별 제어합니다. Compute tile이 유휴 상태이면 전력을 완전히 차단하고, SoC tile의 LP E-core만으로 경량 작업을 처리할 수 있습니다.

Lunar Lake 변형: GPU를 SoC tile에 통합하고, 메모리(LPDDR5X)를 패키지 위에 직접 적층(Package-on-Package)하여 더 작은 폼팩터를 달성했습니다.

커널 토폴로지 영향:

Intel Meteor Lake — Foveros 분리형 4-Tile 설계 Compute Tile (Intel 4) P0 2T P1 2T P2 2T P3 2T P4 2T P5 P-core: Redwood Cove, L2 2MB/코어 E-cluster 0 (E0~E3) Crestmont, L2 4MB 공유 E-cluster 1 (E4~E7) Crestmont, L2 4MB 공유 L3 캐시 12MB (Compute tile 전용) FIVR (독립 전압/주파수) SoC Tile (TSMC N6) LP E-core (2코어) Crestmont, 1~2GHz NPU AI 엔진 미디어 디스플레이 IPU 메모리 컨트롤러 (LPDDR5X) FIVR (독립 전압/주파수) Foveros 인터커넥트 (베이스 다이) GFX Tile (TSMC N5) Xe-LPG GPU (128 EU) IOE Tile (TSMC N6) PCIe Gen5 TB4/USB4 기타 I/O 각 타일: 독립 공정 + 독립 FIVR | Compute tile: 전력 차단 가능 | LP E-core: 항시 가동 커널 토폴로지 인식 CPUID 0x1F: Tile 레벨(type=4)로 크로스 타일 지연 인식 LP E-core: CPUID 0x1A core_type=0x20, ITMT 최저 우선순위, Compute tile L3 미공유 Intel 하이브리드 아키텍처 (Alder Lake/Raptor Lake) P-cores (Golden Cove/Raptor Cove) P0 SMT: 2T P1 SMT: 2T P2 SMT: 2T P3 SMT: 2T P4 SMT: 2T P5 SMT: 2T 각 P-core: L2 1.25MB (개별) E-core 클러스터 E-cluster 0 (E0~E3) L2 2MB 공유, 각 1T E-cluster 1 (E4~E7) L2 2MB 공유, 각 1T Ring Bus + LLC (L3 30MB 공유) Intel Thread Director (HFI) Memory Controller (DDR5) PCIe Gen5 / Thunderbolt GPU (내장) P-core: 고성능 워크로드 | E-core: 백그라운드/효율 워크로드 | Thread Director: HW 기반 분류

ARM 아키텍처

big.LITTLE / DynamIQ

ARM은 이기종 멀티프로세싱(HMP)의 선구자입니다.

기술세대특징
big.LITTLE2011~big/LITTLE 코어가 별도 클러스터, 클러스터 단위 전환 또는 HMP
DynamIQ2017~단일 클러스터 내 이종 코어 혼합 가능, DSU 기반 L3 공유

DynamIQ에서는 하나의 클러스터에 Cortex-X4 + Cortex-A720 + Cortex-A520 같은 3종 코어를 혼합할 수 있습니다.

DSU (DynamIQ Shared Unit)

DSU는 DynamIQ 클러스터의 핵심 IP로, L3 캐시 관리와 클러스터 내 코히런시를 담당합니다.

CMN (Coherent Mesh Network)

ARM 서버 SoC(Neoverse)에서는 CMN(Coherent Mesh Network)으로 다수의 클러스터를 연결합니다.

노드 유형역할
XP (Crosspoint)메시 라우터, 패킷 라우팅
RN-F (Request Node - Full)코어 클러스터 연결점, 풀 코히런시
HN-F (Home Node - Full)SLC(System-Level Cache) 슬라이스, 디렉토리 기반 코히런시
SN-F (Slave Node - Full)메모리 컨트롤러, PCIe 인터페이스
MN (Miscellaneous Node)DVM(Distributed Virtual Memory) 브로드캐스트
/* ARM CMN PMU 드라이버: drivers/perf/arm-cmn.c
 * CMN 메시 토폴로지를 런타임에 탐지 */
static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
{
    void __iomem *reg;
    u64 val;

    /* Configuration 영역에서 메시 크기, 노드 수 읽기 */
    val = readq_relaxed(cmn->base + CMN_CFGM_INFO_GLOBAL);
    cmn->mesh_x = FIELD_GET(CMN_INFO_MESH_X, val);
    cmn->mesh_y = FIELD_GET(CMN_INFO_MESH_Y, val);
    ...
}

Cortex-X/A 시리즈

코어등급특징대표 SoC
Cortex-X4/X925초고성능넓은 OoO, 대형 L2Snapdragon 8 Gen 3, Dimensity 9300
Cortex-A720/A725고성능A78 후속, 균형 잡힌 IPC대부분의 플래그십 SoC
Cortex-A520효율A510 후속, 인오더→아웃오브오더 전환모든 최신 모바일 SoC
Neoverse V2/V3서버SVE2, 넓은 파이프라인, 대형 캐시Graviton 4, Ampere
Neoverse N2/N3서버(효율)코어 수 확장 최적화Graviton 3, Cobalt 100
ARM DynamIQ 클러스터 (모바일 SoC) Cluster 0 (DSU-120) X4L2 2MB A720L2 512K A720L2 512K A720L2 512K L3 12MB (DSU 관리, Snoop Filter) Cluster 1 (DSU-120) A520L2 128K A520L2 128K A520L2 128K A520L2 128K L3 4MB (DSU 관리) CMN / NoC (System Interconnect) DDR5 / LPDDR5X GPU (Mali/Adreno) NPU / DSP PCIe / USB / I/O DynamIQ: 단일 클러스터 내 이종 코어 혼합 | DSU: L3 + 코히런시 | CMN: 칩 전체 메시

ARM 아키텍처 심화

ARM 비대칭 멀티프로세싱 시스템은 코어 종류별 OPP(Operating Performance Point), 에너지 모델, ACPI PPTT 구조가 복합적으로 맞물립니다. 이 섹션에서는 DynamIQ 클러스터 내부 구조, ACPI PPTT 상세, ARM OPP 커널 구현, CPU 용량 계산 방법을 심화 분석합니다.

DynamIQ 클러스터 내부 구조

DynamIQ 클러스터는 하나의 DSU(DynamIQ Shared Unit)가 최대 12개의 이종 코어를 관리합니다. 각 코어는 독립적인 OPP(Operating Performance Point) 테이블을 가질 수 있어, X4/A720/A520 코어가 동시에 서로 다른 주파수로 동작할 수 있습니다.

DSU 버전최대 코어최대 L3Snoop Filter비고
DSU-1108코어16MB내장A55/A75/A77 기반 SoC
DSU-12012코어32MB내장 (확장)X4/A720/A520 혼합, Dimensity 9300+
DSU-AE4코어8MB내장자율주행 ISO 26262 등급
CMN-600128코어HN-F 디렉토리Neoverse 서버 메시
CMN-700256코어HN-F 확장최신 서버 SoC (Neoverse V2 기반)

DynamIQ의 핵심 특징은 독립 전압/주파수 도메인(DVFS Island)입니다. 각 코어(또는 코어 그룹)가 별도의 OPP 테이블을 가지므로, 조성이 다른 코어들이 각자의 최적 주파수에서 동작할 수 있습니다.

ACPI PPTT 상세 구조

PPTT(Processor Properties Topology Table)는 ARM64 ACPI 시스템에서 코어의 계층 구조, 캐시 공유 관계, CPU 능력(capacity)을 기술합니다.

/* drivers/acpi/pptt.c - PPTT 캐시 탐지 */
static struct acpi_pptt_cache *acpi_pptt_find_cache(
    struct acpi_table_header *table,
    struct acpi_pptt_processor *cpu_node,
    int level, int type)
{
    struct acpi_pptt_processor *node = cpu_node;
    while (node) {
        struct acpi_pptt_cache *cache;
        cache = acpi_find_cache_node(table, node, level, type);
        if (cache)
            return cache;
        node = fetch_pptt_node(table, node->parent);
    }
    return NULL;
}

PPTT 계층 레벨과 커널 매핑:

레벨의미커널 필드캐시
0 (Thread)SMT 스레드cpu_topology[cpu].thread_id
1 (Core)물리 코어cpu_topology[cpu].core_idL1/L2 공유
2 (Cluster)DynamIQ 클러스터cpu_topology[cpu].cluster_idDSU L3 공유
3 (Package)SoC 패키지cpu_topology[cpu].package_idSLC(서버)

OPP 커널 구현

리눅스 OPP(Operating Performance Point) 프레임워크는 각 전압/주파수 쌍을 추상화하여 DVFS를 구현합니다.

/* include/linux/pm_opp.h - OPP 데이터 구조 */
struct dev_pm_opp {
    struct list_head node;
    bool             available;
    unsigned long    rate;     /* 주파수 (Hz) */
    unsigned long    u_volt;   /* 전압 (μV) */
    unsigned long    power;    /* 소비전력 (μW) */
};

/* OPP 테이블 API */
struct dev_pm_opp *dev_pm_opp_find_freq_ceil(
    struct device *dev, unsigned long *freq);
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
/* Cortex-A55 OPP 테이블 (Device Tree 예시) */
cpu0_opp_table: opp-table-0 {
    compatible = "operating-points-v2";
    opp-shared;
    opp-400000000 {
        opp-hz = /bits/ 64 <400000000>;
        opp-microvolt = <600000>;
        opp-microwatt = <35000>;
    };
    opp-1800000000 {
        opp-hz = /bits/ 64 <1800000000>;
        opp-microvolt = <850000>;
        opp-microwatt = <480000>;
    };
};

CPU 용량 계산

이종 코어 시스템에서 스케줄러는 각 코어의 상대적 성능을 CPU 용량(capacity)으로 추상화합니다. SCHED_CAPACITY_SCALE = 1024가 최대값이며, 가장 강력한 코어(big 코어)가 1024를 가집니다.

/* drivers/base/arch_topology.c - CPU 용량 정규화 */
void topology_normalize_cpu_scale(void)
{
    unsigned long capacity, max_capacity = 0;
    int cpu;

    for_each_possible_cpu(cpu) {
        capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
        max_capacity = max(max_capacity, capacity);
    }
    for_each_possible_cpu(cpu) {
        capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
        capacity = capacity * SCHED_CAPACITY_SCALE / max_capacity;
        topology_set_cpu_scale(cpu, capacity);
    }
}

/* arch_scale_cpu_capacity() — 스케줄러가 현재 CPU 용량을 조회 */
static inline unsigned long arch_scale_cpu_capacity(int cpu)
{
    return per_cpu(cpu_scale, cpu);
}

Snapdragon 8 Gen 3 (SM8650) 기준 코어별 용량 예시:

코어최대 주파수capacity-dmips-mhzCPU capacity
Cortex-X413.3GHz10241024
Cortex-A72033.15GHz870~895
Cortex-A52042.27GHz480~450

ARM Energy Model 드라이버

Energy Model(EM) 프레임워크는 OPP별 소비전력 정보를 커널에 등록하여 EAS가 에너지 비용을 계산할 수 있도록 합니다.

/* include/linux/energy_model.h - EM 퍼포먼스 상태 */
struct em_perf_state {
    unsigned long frequency;  /* 주파수 (KHz) */
    unsigned long power;       /* 소비전력 (mW) */
    unsigned long cost;        /* power / frequency (에너지 비용 계수) */
};

struct em_perf_domain {
    struct em_perf_state *table;
    int                   nr_perf_states;
    struct cpumask        cpus;
};

/* EM 등록 — drivers/cpufreq/cpufreq-dt.c 등 */
int em_dev_register_perf_domain(struct device *dev,
    unsigned int nr_states,
    struct em_data_callback *cb,
    struct cpumask *cpus,
    bool microwatts);
ARM CMN-700 코히런트 메시 (Neoverse V2 서버 SoC) RN-F 코어 클러스터 0 XP Router HN-F SLC 슬라이스 0 XP Router RN-F 코어 클러스터 1 HN-F SLC 슬라이스 1 XP +MN(DVM) RN-F 코어 클러스터 2 XP Router HN-F SLC 슬라이스 2 SN-F DDR5 채널 0/1 SN-F DDR5 채널 2/3 SN-F CXL / PCIe CMN-700 노드 유형 RN-F (코어 클러스터) HN-F (SLC+디렉토리) XP (메시 라우터) SN-F (메모리/I/O 슬레이브)

아키텍처 간 비교

토폴로지 구조 비교

항목AMD (Zen4/5)Intel (SPR/RPL)ARM (Neoverse/DynamIQ)
기본 단위CCX (8코어+L3)코어 (P/E 구분)클러스터 (DSU)
중간 단위CCD (물리 다이)Tile / E-core 클러스터CMN 메시 노드
인터커넥트Infinity Fabric (IOD 경유)Ring Bus / MeshCMN 메시 / NoC
이종 코어없음 (동종)P-core + E-coreX + A(big) + A(LITTLE)
NUMA 분할NPS1/2/4SNC2/4ACPI PPTT
소켓 간xGMI (IF)UPICCIX / CXL / 커스텀
칩렛/타일CCD + IOD 분리EMIB 타일모놀리식 (서버 일부 칩렛)

캐시 계층 · 코히런시 프로토콜

항목AMDIntelARM
L1D/L1I32K/32K (Zen4: 48K/32K)48K/32K (P), 32K/64K (E)코어별 상이
L21MB/코어1.25-2MB/P, 2-4MB/4E256K~2MB/코어
L3/LLC32MB/CCD슬라이스 분산 (1.875MB/코어)DSU L3 + SLC(서버)
코히런시MOESIMESIFMESI / AMBA CHI
디렉토리Probe FilterSnoop FilterHN-F 디렉토리
코히런시 프로토콜 상세: MESI 상태 전환 다이어그램, MOESI/MESIF 비교, 스누핑 vs 디렉토리 방식의 상세 설명은 CPU 캐시 — 코히런시 프로토콜을 참조하세요.

커널의 토폴로지 탐지

x86 CPUID 기반 탐지

x86 커널은 CPUID 명령어를 사용하여 CPU 토폴로지를 탐지합니다. 핵심 Leaf:

Leaf용도제공 정보
0x0BExtended TopologySMT/Core 레벨 ID, 토폴로지 유형
0x1FV2 Extended TopologyModule/Tile/Die 레벨 추가 (SPR+)
0x8000001EAMD 토폴로지Compute Unit ID, Node(CCD) ID
0x04 / 0x8000001D캐시 토폴로지캐시 레벨별 공유 범위
/* arch/x86/kernel/cpu/topology.c - detect_extended_topology() */
int detect_extended_topology(struct cpuinfo_x86 *c)
{
    unsigned int eax, ebx, ecx, edx;
    unsigned int sub_index = 0;
    unsigned int leaf;

    /* Leaf 0x1F를 우선 시도 (V2), 없으면 0x0B 사용 */
    leaf = 0x1f;
    cpuid_count(leaf, 0, &eax, &ebx, &ecx, &edx);
    if (ebx == 0) {
        leaf = 0x0b;
        cpuid_count(leaf, 0, &eax, &ebx, &ecx, &edx);
        if (ebx == 0)
            return -1;
    }

    /* ECX[15:8] = 토폴로지 레벨 유형
     * 1=SMT, 2=Core, 3=Module, 4=Tile, 5=Die */
    do {
        cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
        unsigned level_type = (ecx >> 8) & 0xff;
        unsigned shift = eax & 0x1f;

        switch (level_type) {
        case 1: /* SMT */
            c->x86_max_threads = ebx & 0xffff;
            break;
        case 2: /* Core */
            c->x86_max_cores = ebx & 0xffff;
            break;
        case 5: /* Die */
            c->x86_max_dies = ebx & 0xffff;
            break;
        }
        sub_index++;
    } while (level_type != 0);

    /* x2APIC ID로 고유 ID 설정 */
    c->topo.apicid = edx;
    return 0;
}
CPUID 명령어 상세: CPUID Leaf의 전체 목록과 인라인 어셈블리 사용법은 CPUID — CPUID 기반 토폴로지 탐지를 참조하세요.

ARM DT/ACPI 기반 탐지

ARM64 시스템은 Device Tree 또는 ACPI PPTT(Processor Properties Topology Table)로 토폴로지를 기술합니다.

/* Device Tree 예시: cpu-map 노드 */
cpus {
    #address-cells = <2>;
    #size-cells = <0>;

    cpu-map {
        cluster0 {     /* big 클러스터 */
            core0 { cpu = <&cpu0>; };
            core1 { cpu = <&cpu1>; };
            core2 { cpu = <&cpu2>; };
            core3 { cpu = <&cpu3>; };
        };
        cluster1 {     /* LITTLE 클러스터 */
            core0 { cpu = <&cpu4>; };
            core1 { cpu = <&cpu5>; };
            core2 { cpu = <&cpu6>; };
            core3 { cpu = <&cpu7>; };
        };
    };

    cpu0: cpu@0 {
        device_type = "cpu";
        compatible = "arm,cortex-x4";
        capacity-dmips-mhz = <1024>;   /* 상대적 성능 */
    };
    cpu4: cpu@100 {
        device_type = "cpu";
        compatible = "arm,cortex-a520";
        capacity-dmips-mhz = <480>;    /* big 대비 ~47% */
    };
};
/* ACPI PPTT 파싱: drivers/acpi/pptt.c */
static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
                                      unsigned int cpu,
                                      int level, int flag)
{
    struct acpi_pptt_processor *node;

    /* PPTT에서 CPU의 프로세서 노드를 탐색
     * level 0 = thread, 1 = core, 2 = cluster, 3 = package */
    node = acpi_find_processor_node(table, cpu);
    while (node && level--) {
        node = fetch_pptt_node(table, node->parent);
    }
    return node ? node->acpi_processor_id : -1;
}

/* arch/arm64/kernel/topology.c - parse_acpi_topology() */
int __init parse_acpi_topology(void)
{
    int cpu;

    for_each_possible_cpu(cpu) {
        int topology_id;
        topology_id = find_acpi_cpu_topology(cpu, 0);  /* thread */
        cpu_topology[cpu].thread_id = topology_id;
        topology_id = find_acpi_cpu_topology(cpu, 1);  /* core */
        cpu_topology[cpu].core_id = topology_id;
        topology_id = find_acpi_cpu_topology(cpu, 2);  /* cluster */
        cpu_topology[cpu].cluster_id = topology_id;
        topology_id = find_acpi_cpu_topology_package(cpu);
        cpu_topology[cpu].package_id = topology_id;
    }
    return 0;
}

초기화 흐름

커널 부팅 시 토폴로지 구축 순서:

  1. BSP(Bootstrap Processor)에서 identify_cpu() → CPUID/PPTT 파싱
  2. AP(Application Processor) 깨움 → smp_callin()에서 개별 토폴로지 ID 설정
  3. topology_init()/sys/devices/system/cpu/cpuN/topology/ sysfs 노출
  4. sched_init_domains() → 토폴로지 기반 스케줄링 도메인 구축
start_kernel()
  → setup_arch()
    → early_cpu_init()         /* x86: CPUID 기본 파싱 */
    → init_intel_cacheinfo()   /* 캐시 토폴로지 */
  → smp_init()
    → cpu_up() (per AP)
      → identify_secondary_cpu()
      → set_cpu_sibling_map()  /* SMT 형제 설정 */
  → sched_init_domains()       /* 스케줄링 도메인 */
  → topology_init()            /* sysfs 노출 */

sysfs 토폴로지 인터페이스

cpu topology

커널은 /sys/devices/system/cpu/cpuN/topology/에 각 논리 CPU의 토폴로지 정보를 노출합니다.

파일설명예시 (AMD EPYC)
physical_package_id물리 소켓 ID0
die_id다이(CCD) ID0~11
cluster_id클러스터 ID (ARM, Intel E-core)0
core_id물리 코어 ID0~95
thread_siblingsSMT 형제 CPU 비트맵00000003
thread_siblings_listSMT 형제 CPU 목록0,96
core_siblings같은 패키지 내 CPU 비트맵(전체)
die_cpus_list같은 다이의 CPU 목록0-7,96-103
# CPU 0의 토폴로지 정보 확인
$ for f in /sys/devices/system/cpu/cpu0/topology/*; do
    echo "$(basename $f): $(cat $f)"
  done
physical_package_id: 0
die_id: 0
cluster_id: 0
core_id: 0
thread_siblings_list: 0,96

cache hierarchy

# CPU 0의 캐시 계층 확인
$ ls /sys/devices/system/cpu/cpu0/cache/
index0  index1  index2  index3

$ for idx in 0 1 2 3; do
    dir=/sys/devices/system/cpu/cpu0/cache/index${idx}
    echo "L$(cat $dir/level) $(cat $dir/type): $(cat $dir/size), shared: $(cat $dir/shared_cpu_list)"
  done
L1 Data: 32K, shared: 0,96          # SMT 형제 공유
L1 Instruction: 32K, shared: 0,96
L2 Unified: 1024K, shared: 0,96     # 코어 단위
L3 Unified: 32768K, shared: 0-7,96-103  # CCD(CCX) 단위

확인 도구

# lscpu: 가장 간단한 토폴로지 요약
$ lscpu
Architecture:        x86_64
CPU(s):              192
Thread(s) per core:  2
Core(s) per socket:  96
Socket(s):           1
NUMA node(s):        4
...

# lstopo (hwloc): 그래픽 토폴로지 뷰
$ lstopo --of ascii
$ lstopo --of png topology.png

# /proc/cpuinfo: 상세 CPU 정보
$ grep -m1 "siblings\|cpu cores\|physical id\|core id" /proc/cpuinfo

# numactl: NUMA 토폴로지 + 메모리
$ numactl --hardware

SMT/Hyper-Threading 심화

SMT(Simultaneous Multi-Threading)는 하나의 물리 코어가 두 개 이상의 논리 스레드를 동시에 실행하는 기술입니다. Intel의 구현을 Hyper-Threading(HT)라고 부릅니다. 공유 자원에서 발생하는 성능 특성과 보안 취약점, 커널 스케줄링 알고리즘을 심화 분석합니다.

공유/분리 자원 비교

SMT의 핵심은 물리 코어 자원을 두 논리 스레드가 어떻게 공유하거나 분리하는지입니다.

자원공유/분리Intel HTAMD SMT비고
실행 유닛 (ALU/FPU/SIMD)공유동적 할당동적 할당스레드별 발행 슬롯 경쟁
ROB (Reorder Buffer)공유절반씩 분할절반씩 분할ROB 크기의 절반만 사용 가능
RS (Reservation Station)공유동적 할당동적 할당두 스레드 합산 → 단일 스레드보다 넓음
분기 예측기 (BTB)공유 ⚠공유공유Spectre V2 취약점의 원인
L1 명령어 캐시공유공유공유코드 밀도 높으면 경합
L1 데이터 캐시공유 ⚠공유공유L1TF 취약점의 원인
TLB (L1 DTLB/ITLB)공유공유공유페이지 테이블 워크 경합 가능
레지스터 파일분리개별개별각 스레드가 완전한 레지스터 집합 보유
프로그램 카운터(IP/PC)분리개별개별독립적인 실행 흐름
LAPIC분리개별개별각 논리 CPU가 독립 APIC ID
SMT 물리 코어 자원 공유 구조 물리 코어 (Physical Core) HW Thread 0 (CPU 0) 레지스터 파일 ROB 절반 PC / RFLAGS RS 슬롯 HW Thread 1 (CPU 1) 레지스터 파일 ROB 절반 PC / RFLAGS RS 슬롯 공유 자원 (두 스레드가 함께 사용) 실행 유닛 (ALU/FPU) SIMD / AVX 유닛 분기 예측기 BTB ⚠ Spectre V2 L1 데이터 캐시 ⚠ L1TF L1 명령어 캐시 L2 캐시 TLB (DTLB/ITLB) — 공유

커널 SMT 스케줄링

커널은 SMT 형제(sibling) 코어를 인식하고 select_idle_sibling()으로 태스크 배치를 최적화합니다.

/* kernel/sched/fair.c - SMT 형제 idle CPU 탐색 */
static int select_idle_sibling(struct task_struct *p,
                               int prev, int target)
{
    struct sched_domain *sd;
    int i, recent_used_cpu;

    /* 1. target CPU가 idle이면 바로 반환 */
    if (available_idle_cpu(target) || sched_idle_cpu(target))
        return target;

    /* 2. prev CPU의 SMT 형제 중 idle 탐색
     *    → L1/L2 캐시를 공유하므로 캐시 온도(warm) 유지 가능 */
    for_each_cpu(i, cpu_smt_mask(prev)) {
        if (available_idle_cpu(i))
            return i;
    }

    /* 3. LLC 도메인 내 idle CPU 탐색 */
    sd = rcu_dereference(per_cpu(sd_llc, target));
    if (sd)
        return select_idle_cpu(p, sd, prev == target, target);

    return target;
}

/* sched_smt_power_savings: SMT 코어 내 두 번째 스레드를
 * 활성화하기 전에 idle 코어를 먼저 채우는 정책 (기본 비활성화) */

SMT 제어

# SMT 상태 확인
$ cat /sys/devices/system/cpu/smt/control
on          # on | off | forceoff | notsupported | notimplemented

$ cat /sys/devices/system/cpu/smt/active
1           # 1=활성화, 0=비활성화

# SMT 런타임 비활성화 (보안/전력 절약 목적)
$ echo off > /sys/devices/system/cpu/smt/control

# 부팅 시 SMT 비활성화 (Spectre/L1TF 완화)
# GRUB_CMDLINE_LINUX="nosmt"  ← /etc/default/grub에 추가

# SMT 비활성화 시 성능 영향 확인
$ lscpu | grep -E "Thread|CPU\(s\)"
Thread(s) per core:  1    # nosmt 시 1
CPU(s):              48   # 물리 코어 수만 활성

SMT와 보안 취약점

SMT의 자원 공유 구조는 여러 사이드채널 공격의 근본 원인입니다. 상세 내용은 13. 보안 취약점과 토폴로지 섹션을 참조하세요.

취약점SMT 공유 자원영향완화
Spectre V2BTB (Branch Target Buffer)sibling 스레드의 분기 패턴 유출IBRS/IBPB/STIBP, Retpoline
L1TF (Foreshadow)L1D 캐시가상 메모리 내용 유출PTI, L1D 플러시, nosmt
MDS (RIDL/Fallout)내부 버퍼 (LFB/SB)파이프라인 버퍼 내용 유출VERW, MD_CLEAR

스케줄링 도메인 계층

SMT → MC → DIE → NUMA

커널 스케줄러는 토폴로지를 기반으로 스케줄링 도메인(sched_domain)의 계층 구조를 구축합니다. 각 레벨은 캐시 공유 범위와 통신 비용을 반영합니다.

도메인 레벨의미SD 플래그대표 예
SMT하이퍼스레드 형제SD_SHARE_CPUCAPACITYCPU 0 ↔ CPU 96
MC (Multi-Core)L3 공유 코어SD_SHARE_PKG_RESOURCESCCD 내 8코어
CL (Cluster)L2 공유 클러스터SD_SHARE_CLS_RESOURCESIntel E-core 4개
DIE같은 다이Intel Tile
NUMANUMA 노드SD_NUMANPS 분할 영역
로드 밸런싱 범위: 스케줄러는 낮은 레벨(SMT)부터 높은 레벨(NUMA)로 올라가며 태스크를 분산합니다. 같은 MC 내에서 밸런싱하면 L3 캐시 히트율을 유지할 수 있고, NUMA 경계를 넘으면 메모리 지연이 증가합니다.
💡

NUMA 경계를 넘는 밸런싱의 구체적인 메커니즘 — Automatic NUMA Balancing, 태스크 선호 노드 결정, NUMA 그룹, 메모리 정책(mbind/set_mempolicy) 등은 NUMA 심화 — NUMA-aware 스케줄링에서 상세히 다룹니다.

도메인 구축

/* kernel/sched/topology.c - 스케줄링 도메인 구축 */

/* 기본 토폴로지 레벨 정의 */
static struct sched_domain_topology_level default_topology[] = {
#ifdef CONFIG_SCHED_SMT
    { cpu_smt_mask,        cpu_smt_flags,   SD_INIT_NAME(SMT) },
#endif
#ifdef CONFIG_SCHED_CLUSTER
    { cpu_clustergroup_mask, cpu_cluster_flags, SD_INIT_NAME(CL) },
#endif
#ifdef CONFIG_SCHED_MC
    { cpu_coregroup_mask, cpu_core_flags,  SD_INIT_NAME(MC) },
#endif
    { cpu_cpu_mask,        SD_INIT_NAME(PKG) },
    { NULL, },
};

/* cpu_coregroup_mask: L3를 공유하는 코어 그룹 반환 */
static const struct cpumask *cpu_coregroup_mask(int cpu)
{
    return topology_core_cpumask(cpu);
}

/* build_sched_domains: 도메인 트리 구축 */
static int build_sched_domains(const struct cpumask *cpu_map,
                                struct sched_domain_attr *attr)
{
    /* 각 토폴로지 레벨에 대해:
     * 1. sched_domain 할당
     * 2. sched_group 링 구성
     * 3. 로드 밸런싱 파라미터 초기화 */
    for_each_sd_topology(tl) {
        for_each_cpu(i, cpu_map) {
            sd = __build_sched_domain(tl, cpu_map, attr, ...);
            ...
        }
    }
    ...
}

도메인 확인

# 스케줄링 도메인 계층 확인
$ ls /sys/kernel/debug/sched/domains/cpu0/
domain0  domain1  domain2  domain3

# 또는 /proc/sys/kernel/sched_domain/
$ ls /proc/sys/kernel/sched_domain/cpu0/
domain0  domain1  domain2  domain3

# 각 도메인의 이름과 범위
$ cat /proc/sys/kernel/sched_domain/cpu0/domain0/name
SMT
$ cat /proc/sys/kernel/sched_domain/cpu0/domain1/name
MC
$ cat /proc/sys/kernel/sched_domain/cpu0/domain2/name
DIE
$ cat /proc/sys/kernel/sched_domain/cpu0/domain3/name
NUMA

# 밸런싱 간격, 플래그 확인
$ cat /proc/sys/kernel/sched_domain/cpu0/domain1/min_interval
4
$ cat /proc/sys/kernel/sched_domain/cpu0/domain1/flags
559
Linux sched_domain 계층 (AMD EPYC NPS4 예시) NUMA domain (node 0..3) — SD_NUMA DIE domain (node 0) DIE domain (node 1) MC: CCD0 (L3 32MB) MC: CCD1 (L3 32MB) MC: CCD2 (L3 32MB) MC: CCD3 (L3 32MB) C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 T0 T1 SMT 스케줄링 도메인 우선순위 (밸런싱 비용 증가 →) SMT (L1/L2 공유) → MC (L3 공유) → DIE (소켓 내) → NUMA (메모리 지역성)

비대칭 스케줄링

ASYM_PACKING

SD_ASYM_PACKING은 SMT 레벨에서 사용되는 플래그로, 하이퍼스레드 형제 코어에 태스크를 비대칭적으로 배치합니다.

/* kernel/sched/fair.c - SMT 비대칭 패킹 로직 */
/*
 * ASYM_PACKING 정책:
 *  - SMT 형제 중 높은 우선순위(smt_gain이 큰) 스레드를 먼저 채움
 *  - 두 번째 스레드는 가능하면 다른 물리 코어로 이동
 *  - 결과: 물리 코어를 최대한 활용하여 IPC 극대화
 *
 * Intel: 보통 thread 0이 우선순위 높음
 * AMD:   Preferred Core 기능으로 최적 코어 선별
 */
static int find_busiest_group(struct lb_env *env,
                              struct sd_lb_stats *sds)
{
    if (env->sd->flags & SD_ASYM_PACKING) {
        /* 우선순위가 낮은 CPU에서 높은 CPU로 태스크 이동 */
        if (sched_asym_prefer(env->dst_cpu, busiest->asym_prefer_cpu))
            return busiest;
    }
    ...
}

ASYM_CPUCAPACITY (EAS)

Energy-Aware Scheduling(EAS)은 이종 코어 시스템에서 성능과 에너지 효율의 균형을 맞추는 스케줄러 기능입니다.

/* kernel/sched/fair.c - find_energy_efficient_cpu() */
static int find_energy_efficient_cpu(struct task_struct *p,
                                     int prev_cpu)
{
    struct root_domain *rd = cpu_rq(prev_cpu)->rd;
    unsigned long best_delta = ULONG_MAX;
    int best_cpu = -1;

    for_each_cpu_and(cpu, sched_domain_span(sd), p->cpus_ptr) {
        unsigned long cur_delta;

        /* 각 CPU(performance domain)별 에너지 소비 예측 */
        cur_delta = compute_energy(p, cpu, pd);
        if (cur_delta < best_delta) {
            best_delta = cur_delta;
            best_cpu = cpu;
        }
    }

    /* 에너지 절감량이 6% 미만이면 prev_cpu 유지 (마이그레이션 비용) */
    if ((prev_delta - best_delta) * 100 < prev_delta * 6)
        return prev_cpu;

    return best_cpu;
}

/* EAS 활성화 조건:
 * 1. SD_ASYM_CPUCAPACITY 플래그 설정
 * 2. Energy Model(EM) 등록 (em_dev_register_perf_domain)
 * 3. CPU 수가 너무 많지 않을 것 (기본 256 이하) */

Intel Thread Director 커널 통합

/* drivers/thermal/intel/intel_hfi.c - HFI 커널 통합 */

/* HFI 인터럽트 핸들러: 하드웨어가 성능/효율 테이블 갱신 시 호출 */
static void intel_hfi_online(unsigned int cpu)
{
    struct hfi_instance *hfi = per_cpu(hfi_instance, cpu);

    /* CPU별 성능 능력(perf_cap)과 에너지 효율(ee_cap) 읽기 */
    u8 perf_cap = hfi->local_table[cpu].perf_cap;
    u8 ee_cap   = hfi->local_table[cpu].ee_cap;

    /* 스케줄러에 CPU 용량 업데이트 알림
     * → CFS의 capacity_of()에 반영
     * → 높은 perf_cap = P-core, 높은 ee_cap = E-core 선호 */
    topology_set_cpu_capacity(cpu, perf_cap);
}

/* IPC 클래스 기반 코어 선택 (커널 6.6+) */
/* Thread Director가 실시간으로 IPC 클래스를 업데이트하면,
 * 스케줄러가 해당 태스크에 적합한 코어 유형을 선택 */

ARM cpu-capacity

ARM에서는 Device Tree의 capacity-dmips-mhz 속성으로 각 코어의 상대적 성능을 지정합니다.

/* drivers/base/arch_topology.c - CPU 용량 설정 */
void topology_normalize_cpu_scale(void)
{
    unsigned long capacity, max_capacity = 0;
    int cpu;

    /* DT의 capacity-dmips-mhz 기반 최대값 탐색 */
    for_each_possible_cpu(cpu) {
        capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
        max_capacity = max(max_capacity, capacity);
    }

    /* 최대 코어 = 1024, 나머지 비례 계산 */
    for_each_possible_cpu(cpu) {
        capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
        capacity = capacity * SCHED_CAPACITY_SCALE / max_capacity;
        topology_set_cpu_scale(cpu, capacity);
    }
}

/* 결과: big 코어 = 1024, LITTLE = ~480, mid = ~700 등
 * → EAS가 이 값을 사용하여 태스크 배치 결정 */

전력 도메인과 EAS

Energy-Aware Scheduling(EAS)은 이종 코어 시스템에서 에너지 모델(Energy Model)을 기반으로 태스크를 가장 에너지 효율적인 CPU에 배치합니다. ARM 모바일 SoC에서 처음 도입되었으며, 리눅스 5.0부터 mainline에 포함되었습니다.

Energy Model 프레임워크 구조

EAS가 동작하려면 세 가지 조건이 모두 충족되어야 합니다:

EAS 활성화 조건:
  1. SD_ASYM_CPUCAPACITY 플래그 — 이종 코어 시스템임을 나타내는 스케줄링 도메인 플래그
  2. Energy Model 등록em_dev_register_perf_domain()으로 각 성능 도메인의 전력 정보 등록
  3. schedutil 거버너 — CPUFreq 거버너가 schedutil이어야 EAS와 연동 가능 (ondemand/performance 불가)
/* kernel/sched/fair.c - EAS 활성화 조건 확인 */
static bool sched_energy_enabled(void)
{
    static int enabled = -1;

    if (enabled == -1)
        enabled = (sysctl_sched_energy_aware &&
                   cpufreq_get_hw_max_freq(0) &&
                   arch_scale_freq_capacity(0) != SCHED_CAPACITY_SCALE);
    return enabled;
}

/* /proc/sys/kernel/sched_energy_aware = 1 이면 EAS 활성화 */

EAS 알고리즘

find_energy_efficient_cpu()는 태스크를 배치할 최적 CPU를 찾는 EAS의 핵심 함수입니다. 각 performance domain(PD)별로 에너지 소비를 예측하고 가장 낮은 PD를 선택합니다.

EAS: find_energy_efficient_cpu() 플로우 wake_up_task(p) 호출 EAS 활성화? (ASYM_CPUCAPACITY+EM) No 기존 CFS select_task_rq Yes 각 performance domain(PD) 순회 compute_energy(p, cpu, pd) 에너지 절감 > 6%? (마이그레이션 임계값) No prev_cpu 유지 Yes best_cpu 반환 (에너지 최적)
/* kernel/sched/fair.c - EAS 핵심 로직 */
static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
{
    struct root_domain *rd = cpu_rq(prev_cpu)->rd;
    unsigned long prev_delta, best_delta = ULONG_MAX;
    int best_cpu = prev_cpu;

    /* prev_cpu에서의 에너지 기준값 계산 */
    prev_delta = compute_energy(p, prev_cpu, find_pd(rd, prev_cpu));

    /* 각 performance domain 순회 */
    rcu_read_lock();
    for_each_pd(pd, rd) {
        int cpu;
        for_each_cpu_and(cpu, perf_domain_span(pd), p->cpus_ptr) {
            unsigned long cur_delta = compute_energy(p, cpu, pd);
            if (cur_delta < best_delta) {
                best_delta = cur_delta;
                best_cpu = cpu;
            }
        }
    }
    rcu_read_unlock();

    /* 에너지 절감이 6% 미만이면 prev_cpu 유지 (마이그레이션 비용 방지) */
    if ((prev_delta - best_delta) * 100 < prev_delta * 6)
        return prev_cpu;

    return best_cpu;
}

OPP와 전력 예산

EAS의 에너지 계산은 각 OPP(Operating Performance Point)의 주파수·전력 정보를 기반으로 합니다. Cortex-A55 기준 예시:

주파수전압전력 (mW)capacitycost (power/freq)
400MHz0.60V3518087.5
800MHz0.70V105360131.3
1200MHz0.75V185540154.2
1600MHz0.80V310720193.8
1800MHz0.85V480810266.7

cost 값의 의미: cost = power / frequency가 낮을수록 주파수 단위당 에너지 효율이 높습니다. EAS는 태스크의 utilization에 맞는 OPP의 cost를 사용하여 에너지 예측값을 계산합니다.

DTPM 계층

DTPM(Dynamic Thermal Power Management)은 열/전력 제약 내에서 SoC 전체의 전력 분배를 관리합니다.

# powercap 인터페이스 확인 (Intel RAPL 포함)
$ ls /sys/class/powercap/
intel-rapl  intel-rapl:0  intel-rapl:0:0  ...

# DTPM 계층 확인 (ARM 시스템)
$ ls /sys/class/powercap/dtpm/
constraint_0_max_power_uw  constraint_0_name
constraint_0_power_limit_uw  energy_uj  ...

Energy Model 디버깅

# EAS 활성화 여부 확인
$ cat /proc/sys/kernel/sched_energy_aware
1

# Energy Model 등록 상태 (debugfs)
$ cat /sys/kernel/debug/energy_model/cpu0/nr_perf_states
5

$ cat /sys/kernel/debug/energy_model/cpu0/table
  freq    power    cost
 400000      35      87
 800000     105     131
1200000     185     154
1600000     310     193
1800000     480     266

# schedutil 거버너 확인 (EAS 필수 조건)
$ cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
schedutil

CPU 격리 심화

CPU 격리(CPU Isolation)는 특정 코어를 리눅스 스케줄러의 일반 태스크 배치에서 제외하여, 실시간 처리나 레이턴시에 민감한 애플리케이션 전용으로 사용하는 기법입니다.

부팅 파라미터 비교

파라미터역할대상완전 격리 여부
isolcpus=N일반 스케줄러 배치 제외CFS/RT 태스크부분 (커널 스레드 미포함)
nohz_full=N틱리스 모드 활성화타이머 인터럽트타이머 오버헤드 제거
rcu_nocbs=NRCU 콜백 오프로드RCU 처리RCU 스레드 분리
irqaffinity=MIRQ 친화도 기본값 설정하드웨어 인터럽트IRQ 특정 코어 제한
kthread_cpus=M커널 스레드 친화도커널 스레드커널 스레드 격리
완전 격리 설정 예시: 코어 2,3을 완전히 격리하려면
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3 irqaffinity=0,1

IRQ 친화도 설정

# IRQ 목록과 현재 친화도 확인
$ cat /proc/interrupts | head -20

# 특정 IRQ를 코어 0,1에만 허용 (비트마스크)
$ echo 3 > /proc/irq/42/smp_affinity      # 0b11 = CPU 0,1

# 또는 목록 형식으로
$ echo 0,1 > /proc/irq/42/smp_affinity_list

# 모든 IRQ를 코어 0,1로 제한 (격리 코어에서 IRQ 제거)
$ for irq in /proc/irq/[0-9]*/smp_affinity_list; do
    echo "0-1" > "$irq" 2>/dev/null
  done

# irqbalance 비활성화 (IRQ 친화도 자동 변경 방지)
$ systemctl stop irqbalance
$ systemctl disable irqbalance

CPU 피닝

/* sched_setaffinity() 시스템 콜 사용 예 */
#include <sched.h>

cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(2, &mask);  /* CPU 2 전용 */
CPU_SET(3, &mask);  /* CPU 3 전용 */

if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
    perror("sched_setaffinity");

/* 커널 내부: kernel/sched/core.c
 * sys_sched_setaffinity() → __set_cpus_allowed_ptr()
 * → migrate_task_to() (필요 시 즉시 마이그레이션) */
# taskset으로 CPU 친화도 설정/확인
$ taskset -c 2,3 ./realtime_app        # 새 프로세스를 CPU 2,3에서 시작
$ taskset -cp 2,3 1234                 # 기존 PID 1234를 CPU 2,3으로 이동
$ taskset -cp 1234                     # 현재 친화도 확인

커널 스레드 격리

/* kernel/kthread.c - 커널 스레드 CPU 바인딩 */

/* 특정 CPU에서만 실행되는 커널 스레드 생성 */
struct task_struct *kthread_create_on_cpu(
    int (*threadfn)(void *data),
    void *data,
    unsigned int cpu,
    const char *namefmt);

/* 이미 생성된 커널 스레드를 특정 CPU에 바인딩 */
void kthread_bind(struct task_struct *p, unsigned int cpu);

/* 예: CPU 핫플러그 워커를 CPU 0에만 허용 */
kthread_bind(cpuhp_thread, 0);

격리 효과 측정

# cyclictest로 wakeup latency 측정 (isolcpus 적용 전후 비교)
# 격리 전:
$ cyclictest -t 1 -p 99 -n -i 1000 -l 100000 -q
T: 0 (12345) P:99 I:1000 C:100000 Min:   8 Act:  12 Avg:  15 Max:   245

# 격리 후 (isolcpus=2 nohz_full=2 rcu_nocbs=2):
$ taskset -c 2 cyclictest -t 1 -p 99 -n -i 1000 -l 100000 -q
T: 0 (12346) P:99 I:1000 C:100000 Min:   4 Act:   5 Avg:   5 Max:    18

# 격리 효과 확인 (최대 레이턴시 245us → 18us)
CPU 격리 상세: cgroup v2의 cpuset 컨트롤러를 사용한 고급 격리 방법은 cpusets 페이지를, 실시간 시스템 튜닝은 실시간 리눅스 페이지를 참조하세요.

보안 취약점과 토폴로지

현대 CPU 아키텍처의 성능 최적화 기능(투기적 실행, 비순차 실행, 분기 예측)은 하드웨어 토폴로지(SMT, 캐시 공유)와 결합하여 심각한 보안 취약점을 만들어냈습니다.

Spectre V1/V2

Spectre V1 (CVE-2017-5753): 배열 범위 검사를 우회하는 조건부 분기 오예측을 통해 임의 메모리를 읽습니다. Spectre V2 (CVE-2017-5715): SMT 형제 스레드 간 BTB(Branch Target Buffer) 공유를 이용해 피해자 프로세스의 간접 분기를 조작합니다.

항목Spectre V1Spectre V2
원인 자원조건부 분기 예측기 (PHT)간접 분기 예측기 (BTB)
공격 방법Array Index Out-of-Bounds 투기BTB 중독(Poisoning) → 임의 가젯 실행
SMT 연관성낮음높음 (sibling 스레드 BTB 공유)
커널 완화array_index_nospec() 배리어IBRS/eIBRS, Retpoline, IBPB
성능 영향~1%IBRS ~10-20%, eIBRS ~3%
/* arch/x86/include/asm/barrier.h - Spectre V1 완화 */
/* array_index_nospec(): 투기적 실행 경로에서 배열 접근 방지 */
static inline unsigned long array_index_mask_nospec(
    unsigned long index, unsigned long size)
{
    /*
     * index < size 이면 mask = ~0UL (모든 비트 1)
     * index >= size 이면 mask = 0 (모든 비트 0)
     * 투기적 실행 경로에서 부호 비트를 이용한 마스킹
     */
    return ~(long)(index | (size - 1UL - index)) >> (BITS_PER_LONG - 1);
}
#define array_index_nospec(index, size)                       (typeof(index))(array_index_mask_nospec(index, size) & (index))

Meltdown과 L1TF

Meltdown (CVE-2017-5754): 커널 메모리를 사용자 공간에서 읽는 취약점. PTI(Page Table Isolation)로 완화합니다. L1TF/Foreshadow (CVE-2018-3620/3646): L1D 캐시 플러시 없이 SMT sibling이 hyper-guest의 L1D 캐시 내용을 투기적으로 접근합니다.

항목MeltdownL1TF
원인 자원페이지 테이블 검사 지연L1D 캐시 (SMT sibling 공유)
완화 방법PTI (KPTI)PTE inversion + L1D 플러시
SMT 영향낮음높음 (nosmt 권장)
성능 영향PTI ~5-30% (syscall 집약적)L1D 플러시 ~10%
# PTI 활성화 여부 확인
$ cat /sys/devices/system/cpu/vulnerabilities/meltdown
Mitigation: PTI

# L1TF 상태 확인
$ cat /sys/devices/system/cpu/vulnerabilities/l1tf
Mitigation: PTE Inversion; VMX: cache flushes, SMT vulnerable

MDS와 SRBDS

MDS(Microarchitectural Data Sampling, CVE-2018-12126/12127/12130): CPU 내부 버퍼(Line Fill Buffer, Store Buffer, Load Port)에서 데이터가 누출됩니다. SRBDS(Special Register Buffer Data Sampling, CVE-2020-0543): RDRAND/RDSEED/EGETKEY 명령어의 결과가 내부 버퍼를 통해 sibling에 노출됩니다.

취약점영향 버퍼완화SMT 영향
MFBDS/RIDLLine Fill BufferVERW + MD_CLEAR높음
MLPDS/FalloutStore BufferVERW + MD_CLEAR높음
MDSUMLoad PortVERW + MD_CLEAR높음
SRBDS특수 레지스터 버퍼SRBDS_CTRL MSR중간
/* arch/x86/kernel/cpu/bugs.c - MDS/SRBDS 완화 */
/* VERW 명령어로 CPU 내부 버퍼 클리어
 * 커널→사용자 전환 시 실행되어 버퍼 내용을 제거 */
static inline void mds_clear_cpu_buffers(void)
{
    static const u16 ds = __KERNEL_DS;
    /* VERW는 메모리 접근 없이 DS 세그먼트 검증 → CPU 버퍼 플러시 */
    asm volatile("verw %[ds]" : : [ds] "m" (ds) : "cc");
}

취약점 sysfs 인터페이스

# 모든 취약점 상태 한 번에 확인
$ grep -r . /sys/devices/system/cpu/vulnerabilities/
/sys/devices/system/cpu/vulnerabilities/spectre_v1:Mitigation: usercopy/swapgs barriers and __user pointer sanitization
/sys/devices/system/cpu/vulnerabilities/spectre_v2:Mitigation: Enhanced / Automatic IBRS; IBPB: conditional; RSB filling; PBRSB-eIBRS: SW sequence
/sys/devices/system/cpu/vulnerabilities/meltdown:Mitigation: PTI
/sys/devices/system/cpu/vulnerabilities/l1tf:Mitigation: PTE Inversion; VMX: cache flushes, SMT vulnerable
/sys/devices/system/cpu/vulnerabilities/mds:Mitigation: Clear CPU buffers; SMT vulnerable
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort:Mitigation: TSX disabled
/sys/devices/system/cpu/vulnerabilities/srbds:Mitigation: Microcode
/sys/devices/system/cpu/vulnerabilities/retbleed:Mitigation: IBRS
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass:Mitigation: Speculative Store Bypass disabled via prctl

완화 오버헤드 종합표

CVE취약점명원인 자원완화 기법SMT 영향성능 오버헤드
CVE-2017-5753Spectre V1PHTarray_index_nospec낮음~1%
CVE-2017-5715Spectre V2BTB (SMT 공유)eIBRS/Retpoline높음~3-20%
CVE-2017-5754Meltdown페이지 테이블PTI (KPTI)낮음~5-30%
CVE-2018-3620L1TFL1D (SMT 공유)PTE inversion + L1D flush매우 높음~10%
CVE-2018-12126MFBDS/RIDLLFB (SMT 공유)VERW/MD_CLEAR높음~3%
CVE-2020-0543SRBDS특수 레지스터 버퍼SRBDS_CTRL MSR중간~1%
CVE-2022-29901RetbleedRSB (RET 예측)IBRS/RSB fill낮음~14-39%
SMT와 보안: L1TF, MDS, Spectre V2는 SMT가 활성화된 상태에서 영향이 크게 증가합니다. 보안이 중요한 환경(클라우드 VM 호스트, 결제 시스템)에서는 nosmt 커널 파라미터로 SMT를 비활성화하는 것이 권장됩니다. 단, 멀티스레드 성능이 최대 50% 감소할 수 있습니다.

커널 소스 참조

x86 토폴로지

파일역할
arch/x86/kernel/cpu/topology.cCPUID 기반 토폴로지 탐지, detect_extended_topology()
arch/x86/kernel/cpu/amd.cAMD 전용 토폴로지 (CPUID 0x8000001E)
arch/x86/kernel/cpu/intel.cIntel 전용 토폴로지, Thread Director
arch/x86/kernel/smpboot.cSMP 부팅, AP 초기화, sibling map
arch/x86/kernel/cpu/cacheinfo.cCPUID 기반 캐시 토폴로지

ARM64 토폴로지

파일역할
arch/arm64/kernel/topology.cARM64 토폴로지 초기화, PPTT 파싱
drivers/base/arch_topology.c아키텍처 공통: cpu-capacity, freq-factor
drivers/acpi/pptt.cACPI PPTT 테이블 파서
drivers/perf/arm-cmn.cCMN 메시 PMU 드라이버

스케줄러 토폴로지

파일역할
kernel/sched/topology.csched_domain 구축, build_sched_domains()
kernel/sched/fair.cCFS 로드 밸런싱, EAS, ASYM_PACKING
include/linux/topology.h토폴로지 매크로/함수 선언
drivers/thermal/intel/intel_hfi.cIntel HFI/Thread Director 드라이버

전력/EAS 관련 파일

파일역할
kernel/sched/cpufreq.cschedutil 거버너, EAS-CPUFreq 연동
drivers/cpufreq/cpufreq-dt.cOPP 테이블 기반 CPUFreq 드라이버
drivers/base/power/opp/core.cOPP 프레임워크 핵심 구현
kernel/power/energy_model.cEnergy Model 프레임워크
drivers/powercap/intel_rapl_common.cIntel RAPL 전력 측정
drivers/base/arch_topology.cCPU 용량 정규화, freq-factor

보안 취약점 완화 파일

파일역할
arch/x86/kernel/cpu/bugs.cSpectre/Meltdown/MDS 완화, 취약점 검출
arch/x86/kernel/cpu/amd.cAMD 전용 취약점 완화 (Retbleed, IBPB)
arch/x86/mm/pti.cPTI (Page Table Isolation) 구현
arch/x86/kernel/itmt.cITMT/HFI 코어 우선순위 설정
arch/x86/include/asm/barrier.h투기적 실행 배리어, array_index_nospec

실전 진단 명령 모음

토폴로지 확인

# 전체 토폴로지 요약
$ lscpu -e=CPU,SOCKET,NODE,CORE,L1d:,L1i:,L2:,L3:,ONLINE

# hwloc: 상세 그래픽 토폴로지 (텍스트)
$ lstopo-no-graphics --of ascii

# 특정 CPU의 상세 토폴로지
$ cat /sys/devices/system/cpu/cpu0/topology/die_id
$ cat /sys/devices/system/cpu/cpu0/topology/core_id
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list

# 캐시 공유 관계 확인
$ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list

# CPU 용량 확인 (ARM/하이브리드)
$ cat /sys/devices/system/cpu/cpu*/cpu_capacity

sched_domain 확인

# 스케줄링 도메인 이름 확인
$ for d in /proc/sys/kernel/sched_domain/cpu0/domain*/; do
    echo "$(basename $d): $(cat ${d}name)"
  done
domain0: SMT
domain1: MC
domain2: DIE
domain3: NUMA

# 도메인별 밸런싱 통계 (debugfs)
$ cat /proc/schedstat | head -20

# 태스크의 현재 CPU, 선호도 확인
$ taskset -cp $$
$ cat /proc/$$/status | grep Cpus_allowed

성능 측정

# inter-CCD vs intra-CCD 지연 비교 (perf)
$ perf stat -e cache-misses,cache-references,L1-dcache-load-misses \
    taskset -c 0,1 ./benchmark    # 같은 CCX 내 코어
$ perf stat -e cache-misses,cache-references,L1-dcache-load-misses \
    taskset -c 0,16 ./benchmark   # 다른 CCD 코어

# NUMA 지연 측정
$ numactl --hardware
$ numactl --cpunodebind=0 --membind=0 ./benchmark   # 로컬
$ numactl --cpunodebind=0 --membind=1 ./benchmark   # 리모트

# Intel Thread Director 상태 확인
$ cat /sys/devices/system/cpu/cpu*/topology/ppin 2>/dev/null
$ dmesg | grep -i "hfi\|thread director"

# 스케줄러 디버깅 (ftrace)
$ echo 1 > /sys/kernel/debug/tracing/events/sched/sched_migrate_task/enable
$ cat /sys/kernel/debug/tracing/trace_pipe | head -50
주의: 프로덕션 환경에서 ftrace를 활성화하면 오버헤드가 발생합니다. 디버깅/프로파일링 목적으로만 사용하고, 측정 후 반드시 비활성화하세요.

EAS 진단

# EAS 활성화 여부 확인
$ cat /proc/sys/kernel/sched_energy_aware
1

# EAS 비활성화 (디버깅용)
$ echo 0 > /proc/sys/kernel/sched_energy_aware

# Energy Model 등록 상태
$ ls /sys/kernel/debug/energy_model/
cpu0  cpu4  cpu7   # 각 performance domain 대표 CPU

$ cat /sys/kernel/debug/energy_model/cpu0/table

# schedutil 상태 확인
$ cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
schedutil

# CPU별 현재 utilization 확인 (cfs bandwidth)
$ cat /proc/sched_debug | grep -A 5 "cpu#0"

# perf로 EAS 동작 추적
$ perf sched record -g -- sleep 5
$ perf sched map

보안 취약점 진단

# 모든 취약점 상태 한 번에 확인
$ grep -r . /sys/devices/system/cpu/vulnerabilities/

# SMT 상태와 보안 권고 확인
$ cat /sys/devices/system/cpu/smt/active
$ dmesg | grep -i "SMT\|spectre\|meltdown\|mds"

# spectre_v2 완화 방법 확인
$ cat /sys/devices/system/cpu/vulnerabilities/spectre_v2

# 커널 부팅 파라미터에서 완화 설정 확인
$ cat /proc/cmdline | tr ' ' '
' | grep -E "spectre|mds|pti|ibrs|retpoline"

# 완화 비활성화 시 성능 차이 측정 (개발/테스트 환경 전용)
# GRUB에 mitigations=off 추가 후 비교

CPU 격리 진단

# 격리된 CPU 목록 확인
$ cat /sys/devices/system/cpu/isolated
2-3

# nohz_full 활성화 CPU 확인
$ cat /sys/devices/system/cpu/nohz_full
2-3

# 격리 CPU에서 실행 중인 프로세스 확인
$ ps -eo pid,psr,comm | awk '$2 == 2 || $2 == 3'

# IRQ 친화도 현황
$ for i in $(ls /proc/irq/); do
    aff=$(cat /proc/irq/$i/smp_affinity_list 2>/dev/null)
    [ -n "$aff" ] && echo "IRQ $i: $aff"
  done

# 격리 효과 cyclictest 측정
$ taskset -c 2 cyclictest -t 1 -p 99 -n -i 1000 -l 10000 -q

CPU 토폴로지와 관련된 다른 주제를 더 깊이 이해하고 싶다면 다음 문서를 참고하세요.