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=0Node 0의 코어만 사용
메모리 노드 바인딩numactl --membind=0Node 0의 메모리만 할당
선호도 설정numactl --preferred=0Node 0 선호, 부족 시 다른 노드

Ⅴ. 지식 그래프

CPU 친화성 Soft/Hard Affinity
├── 핵심 개념
│   ├── CPU 어피니티 (코어 집합 지정)
│   ├── 소프트 어피니티 (OS 선호 정책)
│   └── 하드 어피니티 (강제 바인딩)
├── CPU 마스크 비트맵
│   ├── 각 비트가 코어를 표현
│   ├── sched_setaffinity()로 설정
│   └── taskset으로 명령행 제어
├── 소프트 어피니티 특징
│   ├── 이전 코어 선호 (캐시 지역성)
│   ├── 마이그레이션 허용 (유연성)
│   └── 부하 분산 자동 조정
├── 하드 어피니티 특징
│   ├── 지정 코어 외 실행 불가
│   ├── 결정적 실행 보장
│   └── 실시간 시스템에 적합
├── 위험 및 주의사항
│   ├── 로드 불균형 (특정 코어 과부하)
│   ├── 오버커밋 (코어 수 초과 스레드)
│   └── 유연성 상실 (부하 변화 미대응)
└── NUMA 관계
    ├── 같은 노드에 스레드+메모리 배치
    ├── numactl로 노드 단위 제어
    └── 원격 메모리 접근 지연 최소화

약어 정리

약어Full Name
CPUCentral Processing Unit
NUMANon-Uniform Memory Access
QPIQuickPath Interconnect
TLBTranslation Lookaside Buffer
PIDProcess Identifier

3줄 어린이 설명

컴퓨터의 일꾼이 어느 작업대에서 일할지 정하는 규칙입니다. 소프트는 "가능하면 이 자리를 써요", 하드는 "무조건 이 자리만 써요"입니다. 자리를 너무 꽉 잡으면 다른 자리가 놀기 때문에 균형이 중요해요.