CPU 친화성 Soft/Hard Affinity
Ⅰ. CPU 어피니티 개념
1. 정의
CPU 어피니티(CPU Affinity)는 프로세스나 스레드가 실행될 CPU 코어의 집합을 지정 또는 선호하는 속성이다. 운영체제 스케줄러의 스레드 배치 정책에 직접적인 영향을 미친다.
비유: 아이가 항상 앉던 자리를 선호하는 것(Soft)과, 담임 선생님이 특정 자리를 지정하는 것(Hard)의 차이와 같다.
┌─────────── CPU Affinity Overview ────────────┐
│ │
│ 프로세스 A ──── CPU Mask: 0,1,2,3 │
│ 프로세스 B ──── CPU Mask: 0,1 │
│ 프로세스 C ──── CPU Mask: 2,3 │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Core 0│ │Core 1│ │Core 2│ │Core 3│ │
│ │ A,B │ │ A,B │ │ A,C │ │ A,C │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │
└────────────────────────────────────────────────┘
2. 소프트 어피니티 (Soft Affinity)
운영체제가 이전에 실행했던 코어를 선호하도록 하는 정책이다. 강제성이 없으며, 부하 분산이 필요한 경우 다른 코어로 마이그레이션할 수 있다.
- 구현 방식: 스케줄러의 마이그레이션 저항도(migration resistance) 설정
- 목표: 캐시 지역성 유지와 부하 분산의 균형
┌────────── Soft Affinity 동작 ──────────┐
│ │
│ 시간 T1: Thread X ──> Core 0 실행 │
│ 시간 T2: Thread X ──> Core 0 선호 │
│ (OS가 Core 0에 머무르게 함) │
│ 시간 T3: Core 0 과부하 시 │
│ Thread X ──> Core 2 이동 (허용)│
│ │
│ 특징: 선호하지만 강제하지 않음 │
│ │
└──────────────────────────────────────────┘
3. 하드 어피니티 (Hard Affinity)
프로세스가 지정된 CPU 코어 집합 외에서는 절대 실행되지 않도록 강제하는 설정이다.
- 구현 방식:
sched_setaffinity()시스템 콜 - 목표: 결정적 실행, 실시간 성능 보장
┌────────── Hard Affinity 동작 ───────────┐
│ │
│ 설정: sched_setaffinity(pid, mask=0x03) │
│ -> Core 0, 1만 허용 │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Core 0│ │Core 1│ │Core 2│ │Core 3│ │
│ │ OK │ │ OK │ │ X │ │ X │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │
│ 스케줤러가 Core 2,3으로 이동 불가 │
│ │
└───────────────────────────────────────────┘
Ⅱ. CPU 마스크 비트맵
1. 비트마스크 구조
CPU 어피니티 마스크는 각 비트가 코어를 나타내는 정수 값이다.
┌────────────── CPU Mask Bit Layout ──────────────┐
│ │
│ Bit Position: 7 6 5 4 3 2 1 0 │
│ Core Number: 7 6 5 4 3 2 1 0 │
│ │
│ Mask = 0xFF (11111111): Core 0~7 모두 허용 │
│ Mask = 0x03 (00000011): Core 0, 1만 허용 │
│ Mask = 0x0A (00001010): Core 1, 3만 허용 │
│ Mask = 0x55 (01010101): Core 0,2,4,6만 허용 │
│ │
└───────────────────────────────────────────────────┘
┌─────────── 실제 적용 예 ─────────────┐
│ │
│ 8코어 시스템, 4개 워커 스레드: │
│ │
│ Worker-0: mask=0x01 -> Core 0 전용 │
│ Worker-1: mask=0x02 -> Core 1 전용 │
│ Worker-2: mask=0x04 -> Core 2 전용 │
│ Worker-3: mask=0x08 -> Core 3 전용 │
│ │
│ Core 4~7: OS/시스템 예약 │
│ │
└───────────────────────────────────────┘
2. 리눅스에서의 확인과 설정
# 프로세스의 CPU 어피니티 확인
taskset -p <PID>
# 프로세스를 특정 코어에 고정하여 실행
taskset -c 0,1 ./my_app
# cgroups를 통한 그룹 설정
echo "0-1" > /sys/fs/cgroup/cpuset/mygroup/cpuset.cpus
Ⅲ. 로드 불균형 위험
1. 과도한 고정의 문제
┌────── 하드 어피니티 로드 불균형 ──────┐
│ │
│ BEFORE (정균분산): │
│ Core 0: ████░░░░░░ 40% │
│ Core 1: ████░░░░░░ 40% │
│ Core 2: ████░░░░░░ 40% │
│ Core 3: ████░░░░░░ 40% │
│ │
│ AFTER (하드 어피니티 과도한 적용): │
│ Core 0: ██████████ 100% (과부하!) │
│ Core 1: ██░░░░░░░░ 20% │
│ Core 2: ░░░░░░░░░░ 0% (유휴) │
│ Core 3: ░░░░░░░░░░ 0% (유휴) │
│ │
│ 총 처리량 저하 발생 │
│ │
└────────────────────────────────────────┘
2. 위험 요소
| 위험 | 설명 | 대응 |
|---|---|---|
| 로드 불균형 | 특정 코어만 과부하 | 실시간 모니터링 |
| 오버커밋 | 코어 수보다 많은 스레드 고정 | 코어 수에 맞게 조정 |
| 유연성 상실 | 부하 변화에 대응 불가 | 소프트 어피니티 검토 |
| 핫스팟 | 특정 코어 온도 상승 | 균형 배치 |
비유: 4개의 계산대가 있는 마트에서 모든 손님을 1번 계산대로만 보내면 혼잡해지는 것과 같다.
Ⅳ. NUMA와의 관계
1. NUMA 시스템에서의 어피니티
┌──────────── NUMA Node + CPU Affinity ────────────┐
│ │
│ NUMA Node 0 NUMA Node 1 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Local Mem 0 │ │ Local Mem 1 │ │
│ │ (빠름) │ │ (빠름) │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │C0 C1 C2 C3│ │C4 C5 C6 C7│ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
│ └──── QPI/Interconnect ───┘ │
│ (원격 메모리 접근: 느림) │
│ │
│ 최적: 스레드와 메모리를 같은 노드에 고정 │
│ │
└─────────────────────────────────────────────────────┘
2. NUMA 인식 어피니티 설정
| 설정 | 명령어 | 효과 |
|---|---|---|
| CPU 노드 바인딩 | numactl --cpunodebind=0 | Node 0의 코어만 사용 |
| 메모리 노드 바인딩 | numactl --membind=0 | Node 0의 메모리만 할당 |
| 선호도 설정 | numactl --preferred=0 | Node 0 선호, 부족 시 다른 노드 |
Ⅴ. 지식 그래프
CPU 친화성 Soft/Hard Affinity
├── 핵심 개념
│ ├── CPU 어피니티 (코어 집합 지정)
│ ├── 소프트 어피니티 (OS 선호 정책)
│ └── 하드 어피니티 (강제 바인딩)
├── CPU 마스크 비트맵
│ ├── 각 비트가 코어를 표현
│ ├── sched_setaffinity()로 설정
│ └── taskset으로 명령행 제어
├── 소프트 어피니티 특징
│ ├── 이전 코어 선호 (캐시 지역성)
│ ├── 마이그레이션 허용 (유연성)
│ └── 부하 분산 자동 조정
├── 하드 어피니티 특징
│ ├── 지정 코어 외 실행 불가
│ ├── 결정적 실행 보장
│ └── 실시간 시스템에 적합
├── 위험 및 주의사항
│ ├── 로드 불균형 (특정 코어 과부하)
│ ├── 오버커밋 (코어 수 초과 스레드)
│ └── 유연성 상실 (부하 변화 미대응)
└── NUMA 관계
├── 같은 노드에 스레드+메모리 배치
├── numactl로 노드 단위 제어
└── 원격 메모리 접근 지연 최소화
약어 정리
| 약어 | Full Name |
|---|---|
| CPU | Central Processing Unit |
| NUMA | Non-Uniform Memory Access |
| QPI | QuickPath Interconnect |
| TLB | Translation Lookaside Buffer |
| PID | Process Identifier |
3줄 어린이 설명
컴퓨터의 일꾼이 어느 작업대에서 일할지 정하는 규칙입니다. 소프트는 "가능하면 이 자리를 써요", 하드는 "무조건 이 자리만 써요"입니다. 자리를 너무 꽉 잡으면 다른 자리가 놀기 때문에 균형이 중요해요.