RAPL & powercap
Linux powercap 프레임워크와 Intel RAPL의 실전 활용을 다룹니다. package/core/uncore/DRAM 도메인별 에너지 카운터 해석, PL1·PL2·time window 기반 전력 제한 모델, MSR·sysfs·hwmon 인터페이스 사용법, thermal·cpufreq와의 상호작용, 전력 캡 적용 시 성능 회귀 검증, 데이터센터 전력 예산 운영 시나리오와 모니터링 지표까지 종합적으로 정리합니다.
핵심 요약
- RAPL (Running Average Power Limit) — Intel/AMD 프로세서의 하드웨어 전력 모니터링 및 제한 인터페이스입니다.
- powercap 프레임워크 — 커널의 통합 전력 상한 설정 인터페이스. RAPL이 대표적인 백엔드입니다.
- 전력 도메인 — package(전체 소켓), core(CPU 코어), dram(메모리), uncore(iGPU) 등으로 분리하여 측정합니다.
- PL1/PL2 — 장기(Long-Term) 및 단기(Short-Term) 전력 제한. TDP와 Turbo 성능을 제어합니다.
- 에너지 카운터 — 마이크로줄(μJ) 단위로 실시간 에너지 소비를 측정하여 전력 효율을 분석합니다.
단계별 이해
- 현재 전력 확인 —
cat /sys/class/powercap/intel-rapl:0/energy_uj로 현재 소비 에너지를 확인합니다.또는
turbostat --show Package,Core,Uncore --interval 1로 실시간 전력을 모니터링합니다. - 도메인별 측정 —
perf stat -e power/energy-pkg/,power/energy-cores/ ./workload로 워크로드의 에너지 소비를 측정합니다.package와 core 도메인을 분리하여 CPU vs 언코어 전력 비중을 파악합니다.
- 전력 제한 설정 —
echo 25000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw로 PL1을 25W로 제한합니다.열 문제나 배터리 수명 연장이 필요할 때 TDP를 동적으로 조절합니다.
- 효과 검증 — 전력 제한 전후로 벤치마크 성능과 온도/전력을 비교합니다.
stress-ng --cpu 8 --timeout 60s로 부하를 주고turbostat로 차이를 확인하세요.
powercap & RAPL
powercap 프레임워크는 전력 상한(power capping)을 설정하는 통합 인터페이스를 제공합니다. 가장 대표적인 백엔드는 Intel/AMD의 RAPL(Running Average Power Limit)로, 프로세서 패키지·코어·메모리 등 전력 도메인별 에너지 소비를 모니터링하고 제한할 수 있습니다.
powercap/RAPL 아키텍처
RAPL은 하드웨어 MSR(또는 TPMI)에서 에너지 카운터와 전력 제한을 읽고 쓰는 커널 드라이버를 통해 powercap 프레임워크에 등록됩니다. 사용자 공간은 sysfs 또는 perf 이벤트를 통해 접근합니다.
RAPL 도메인
RAPL은 프로세서 내부를 여러 전력 도메인(power domain)으로 분리하여 도메인별 에너지 측정과 전력 제한을 제공합니다. 지원 도메인은 프로세서 세대에 따라 다릅니다.
| 도메인 | 설명 | Intel | AMD |
|---|---|---|---|
| package | 소켓 전체 (CPU + 언코어 + iGPU) | Sandy Bridge+ (2세대+) | Zen (Family 17h+) |
| core (PP0) | CPU 코어만 | Sandy Bridge+ | Zen+ |
| uncore (PP1) | iGPU / 언코어 | 클라이언트 전용 (Sandy Bridge+) | — |
| dram | 메모리 컨트롤러/DRAM | 서버 (Sandy Bridge-EP+), 클라이언트 (Haswell+) | — |
| psys | 플랫폼 전체 (SoC + PCH) | Skylake+ (모바일/NUC) | — |
psys 도메인은 CPU뿐 아니라 PCH, 온보드 디바이스를 포함한 플랫폼 전체 전력을 측정합니다. 노트북/NUC 등 배터리 기반 시스템에서 전체 시스템 전력 예산(power budget) 관리에 유용합니다.도메인별 전력 분포
워크로드 유형에 따라 도메인별 전력 소비 비중이 크게 달라집니다. 다음은 실제 측정 데이터입니다:
| 워크로드 | Package | Core | Uncore (iGPU) | DRAM | 특징 |
|---|---|---|---|---|---|
| Idle (유휴) | 8W | 2W (25%) | 3W (37%) | 3W (37%) | 백그라운드 활동 |
| CPU 집약 (컴파일) | 65W | 48W (74%) | 10W (15%) | 7W (11%) | 코어 전력 지배적 |
| 메모리 집약 (STREAM) | 45W | 20W (44%) | 8W (18%) | 17W (38%) | DRAM 전력 증가 |
| GPU 렌더링 (iGPU) | 55W | 15W (27%) | 32W (58%) | 8W (15%) | Uncore 전력 급증 |
| 혼합 (웹 브라우징) | 25W | 12W (48%) | 8W (32%) | 5W (20%) | 균형 분포 |
측정 환경: Intel Core i7-1165G7 (Tiger Lake, 28W TDP), DDR4-3200 16GB, 유휴 배경 프로세스 최소화
- CPU 집약적 워크로드는 Core 도메인이 70% 이상 차지 — CPU 주파수/전압 최적화가 효과적
- 메모리 집약적 워크로드는 DRAM이 30~40% — 메모리 주파수 낮추기로 절전 가능
- iGPU 활성 시 Uncore가 50% 이상 — 외장 GPU 사용 시 iGPU 비활성화로 10W 이상 절감
- Idle 시에도 8W 소비 — C-state 진입 최적화와 디바이스 runtime PM 중요
PL1/PL2/PL3/PL4 전력 제한 계층
RAPL은 최대 4단계의 전력 제한(Power Limit)을 제공합니다. 각 단계는 허용 전력과 시간 윈도우가 다르며, 하드웨어가 자율적으로 스로틀링을 적용합니다.
| 레벨 | 명칭 | 시간 윈도우 | 동작 방식 | MSR |
|---|---|---|---|---|
| PL1 | Long-Term (장기) | 1~128초 (설정 가능) | 지속 가능한 TDP. 윈도우 내 평균 전력이 PL1 이하 유지 | MSR_PKG_POWER_LIMIT [14:0] |
| PL2 | Short-Term (단기) | 1~10ms 수준 | Turbo Boost 시 허용하는 순간 최대 전력. PL1의 1.2~1.5배 | MSR_PKG_POWER_LIMIT [46:32] |
| PL3 | Peak Power (피크) | ~10ms | 배터리 기반 시스템의 순간 피크 제한 (Kaby Lake+) | MSR_PL3_CONTROL |
| PL4 | Max Power (최대) | 즉시 | 하드웨어 즉시 차단 — 전류/전력 한계 초과 시 주파수 급강하 | MSR_VR_CURRENT_CONFIG |
PL 전력 제한 타임라인
다음 다이어그램은 워크로드 시작 시 PL1/PL2/PL4가 시간에 따라 어떻게 작동하는지 보여줍니다:
/* powercap sysfs에서 PL1/PL2 확인 및 설정 */
# PL1 (constraint_0) 확인
cat /sys/class/powercap/intel-rapl:0/constraint_0_name # "long_term"
cat /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw # 현재 PL1 (μW)
cat /sys/class/powercap/intel-rapl:0/constraint_0_time_window_us # 시간 윈도우 (μs)
# PL2 (constraint_1) 확인
cat /sys/class/powercap/intel-rapl:0/constraint_1_name # "short_term"
cat /sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw
# PL1을 15W로 설정 (root 권한 필요)
echo 15000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
powercap sysfs 인터페이스
RAPL 커널 드라이버 구조
커널의 RAPL 지원은 공통 로직과 하드웨어 백엔드로 분리된 모듈러 구조입니다.
| 모듈 | 경로 | 역할 |
|---|---|---|
| intel_rapl_common | drivers/powercap/intel_rapl_common.c | RAPL 도메인 관리, powercap zone 등록, 에너지 단위 변환, PL 읽기/쓰기 공통 로직 |
| intel_rapl_msr | drivers/powercap/intel_rapl_msr.c | MSR 기반 백엔드 — 대부분의 Intel/AMD CPU. rdmsr/wrmsr로 RAPL MSR 접근 |
| intel_rapl_tpmi | drivers/powercap/intel_rapl_tpmi.c | TPMI(Topology Aware Register and PM Capsule Interface) 백엔드 — Meteor Lake+ MMIO 기반 |
| amd_energy | drivers/hwmon/amd_energy.c | AMD Zen hwmon 드라이버 (powercap 미사용, hwmon으로 에너지 노출) |
/* intel_rapl_common.c — 핵심 구조체 */
struct rapl_domain {
const char *name;
enum rapl_domain_type id; /* RAPL_DOMAIN_PACKAGE, PP0, PP1, DRAM, PLATFORM */
u64 energy_unit; /* 에너지 단위 (MSR_RAPL_POWER_UNIT에서 파생) */
u64 power_unit; /* 전력 단위 */
struct powercap_zone power_zone; /* powercap 프레임워크 zone */
struct rapl_package *rp; /* 소속 패키지 */
};
struct rapl_package {
unsigned int id; /* 패키지(소켓) ID */
unsigned int nr_domains; /* 이 패키지의 도메인 수 */
struct rapl_domain *domains; /* 도메인 배열 */
struct rapl_if_priv *priv; /* 백엔드별 private 데이터 */
};
# RAPL 모듈 로드 확인
lsmod | grep rapl
# intel_rapl_msr 20480 0
# intel_rapl_common 36864 1 intel_rapl_msr
# powercap 16384 1 intel_rapl_common
# 에너지 단위 확인 (MSR_RAPL_POWER_UNIT, 606h)
rdmsr 0x606
# 결과 해석: bits[12:8]=에너지 단위, bits[3:0]=전력 단위, bits[19:16]=시간 단위
TPMI (Topology Aware Register and PM Capsule Interface)
TPMI는 Intel Meteor Lake(클라이언트, 2023) 및 Sapphire Rapids(서버, 4세대 Xeon) 이후 도입된 MMIO 기반 PM 레지스터 인터페이스입니다. PCIe 표준 기반의 아키텍처 모델로 설계되어, 기존 MSR의 모델별 코드 유지보수 부담을 줄이고 멀티 다이/칩렛 아키텍처에서 다이별(per-die) 세밀한 전력 관리를 지원합니다. Granite Rapids(Xeon 6 P-core), Sierra Forest(Xeon 6 E-core), Clearwater Forest 등 후속 세대에서 전면 채택되었습니다.
rdmsr/wrmsr) 직렬 접근이지만, TPMI는 PCI MMIO BAR를 통해 토폴로지 인식(topology-aware) 병렬 접근이 가능합니다. RAPL뿐 아니라 SST, Uncore 주파수 제어, 성능 제한 사유(PLR) 등 다양한 PM 기능이 TPMI를 통해 통합 제공됩니다.TPMI vs MSR 비교
| 항목 | MSR 방식 | TPMI 방식 |
|---|---|---|
| 접근 방식 | rdmsr/wrmsr (CPU 명령어) | MMIO (readq/writeq, PCI BAR 매핑) |
| 토폴로지 | CPU별 (per-CPU), IPI로 원격 CPU 접근 | 다이별 (per-die), 직접 MMIO 매핑 |
| 확장성 | 다이 수 증가 시 MSR 주소 충돌 우려 | PCI VSEC + PFS로 동적 열거, 다이별 독립 주소 공간 |
| 병렬 접근 | MSR 접근은 직렬화 (serialize) | 서로 다른 다이의 MMIO에 동시 접근 가능 |
| 기능 발견 | CPUID + MSR 존재 여부 수동 확인 | PFS(PM Feature Structure)로 자동 열거 |
| 디바이스 모델 | 직접 MSR 접근, 플랫폼 디바이스 없음 | PCI auxiliary 디바이스로 등록, 표준 드라이버 모델 |
| 유지보수 | CPU 모델별 MSR 테이블 유지 필요 | 아키텍처 인터페이스 — 세대 간 호환 유지 |
| 토폴로지 계층 | 소켓 → CPU (flat) | 소켓 → 다이 → 전력 도메인 → 패브릭 클러스터 |
| 지원 범위 | Sandy Bridge (2011) 이후 전 세대 | Meteor Lake/Sapphire Rapids (2023) 이후 |
TPMI 아키텍처
TPMI는 PCI VSEC(Vendor Specific Extended Capability, ID=66)를 통해 발견됩니다. Intel VSEC 드라이버(intel_vsec.c)가 OOB(Out-of-Band) PCI 디바이스의 VSEC/DVSEC 구조를 스캔하여 TPMI를 감지하면, auxiliary 버스에 TPMI 코어 디바이스를 생성합니다. TPMI 코어는 VSEC 헤더의 tBIR(BAR Indicator Register) 필드로 대상 PCI BAR를 식별하고, Address 필드로 BAR 내 PFS 시작 오프셋을 계산합니다.
PCI VSEC 발견 및 PFS 파싱
TPMI는 PCIe 설정 공간의 VSEC(Vendor Specific Extended Capability)를 통해 발견됩니다. Intel VSEC 드라이버(intel_vsec.c)가 TPMI 타입의 VSEC를 감지하면 TPMI 코어 드라이버를 로드하고, TPMI 코어는 MMIO에 매핑된 PFS(PM Feature Structure) 테이블을 파싱합니다.
/* PFS (PM Feature Structure) 엔트리 — 하드웨어 비트필드 레이아웃 */
/* drivers/platform/x86/intel/vsec_tpmi.c (커널 6.13+, 이전: tpmi.c) */
struct intel_tpmi_pfs_entry {
u64 tpmi_id:8; /* PM 기능 식별자 (0=RAPL, 2=UFS, 5=SST ...) */
u64 num_entries:8; /* 인스턴스 수 (전력 도메인/다이 수와 대응) */
u64 entry_size:16; /* 인스턴스 MMIO 블록 크기 (32비트 워드 단위) */
u64 cap_offset:16; /* PM_Features 베이스로부터 오프셋 (KB 단위) */
u64 attribute:2; /* 속성 플래그 (읽기 전용, 잠금 등) */
u64 reserved:14;
} __packed;
/* TPMI 코어의 PFS 파싱 흐름 */
tpmi_pfs_init(tpmi_info):
/* 1. PCI BAR0에서 PFS 헤더 읽기 */
pfs_start = devm_ioremap_resource(dev, &pci_resource);
/* 2. PFS 엔트리 순회하며 기능 열거 */
for (i = 0; i < pfs_count; i++) {
read_pfs_entry(&pfs[i]);
/* 3. 기능별 MMIO 영역 매핑 */
feature_mem = pfs_start + pfs[i].cap_offset;
/* 4. auxiliary 디바이스 생성 (intel_rapl_tpmi, isst_tpmi 등) */
intel_vsec_add_aux(dev, NULL, &feature_info, name);
}
TPMI Feature ID 매핑
각 PM 기능은 고유한 TPMI ID를 가지며, PFS 테이블에서 이 ID를 통해 발견됩니다. 커널은 ID에 따라 해당 feature 드라이버의 auxiliary 디바이스를 생성합니다.
| ID | 이름 | 커널 드라이버 | 설명 |
|---|---|---|---|
| 0 | RAPL | intel_rapl_tpmi | MMIO 기반 RAPL 도메인 — 에너지 측정 및 전력 제한 |
| 1 | PEM | (커널 내부) | Performance and Energy Monitoring — 성능/에너지 모니터링 |
| 2 | UFS | uncore-freq-tpmi | Uncore Frequency Scaling — 다이별 언코어 주파수 제어 |
| 5 | SST | isst_tpmi | Intel Speed Select Technology — PP/BF/TF/CP 프로파일 |
| 8 | PLR | tpmi_plr | Performance Limit Reasons — 스로틀링 원인 보고 (debugfs) |
| 10 | UMS | uncore-freq-tpmi | Uncore Mesh/SoC 주파수 제어 |
| 12 | PWR_DMN | tpmi_power_domains | 전력 도메인 파티셔닝 |
| 0x81 | INFO | (TPMI 코어 내부) | CPU↔PCI 토폴로지 매핑 (패키지 ID, PCI BDF). 실제 PM 기능이 아닌 메타 정보 |
TPMI_INFO_ID(0x81)는 CPU 소켓과 PCI 디바이스 간의 매핑 정보를 제공하는 특수 pseudo-feature입니다. TPMI 코어가 이 정보를 읽어 intel_tpmi_plat_info의 package_id와 PCI BDF를 채웁니다.TPMI 코어 구조체
/* include/linux/intel_tpmi.h — TPMI API 핵심 구조체 */
/* Feature 드라이버가 TPMI 코어에서 받는 플랫폼 정보 */
struct intel_tpmi_plat_info {
u8 package_id; /* CPU 소켓(패키지) ID */
u8 bus_number; /* PCI 버스 번호 */
u8 device_number; /* PCI 디바이스 번호 */
u8 function_number; /* PCI 펑션 번호 */
u8 segment; /* PCI 세그먼트 ID */
u8 partition; /* 패키지 파티션 ID */
u16 cdie_mask; /* 현재 파티션의 컴퓨트 다이 비트맵 */
};
/* TPMI 코어 내부 — 디바이스별 기능 관리 */
struct intel_tpmi_info {
struct auxiliary_device *vsec_dev; /* 부모 VSEC auxiliary 디바이스 */
int feature_count; /* 발견된 PM 기능 수 */
struct intel_tpmi_pm_feature *tpmi_features; /* PM 기능 배열 */
};
/* PM 기능 인스턴스 정보 */
struct intel_tpmi_pm_feature {
struct intel_tpmi_pfs_entry pfs_header; /* 하드웨어 PFS 헤더 */
unsigned int vsec_offset; /* MMIO 시작 주소 (바이트) */
/* vsec_offset = VSEC Address + cap_offset(KB) * 1024 */
};
/* CPU↔PCI 토폴로지 매핑 헤더 (TPMI_INFO_ID=0x81에서 읽음) */
struct tpmi_info_header {
u64 fn:3; /* PCI Function 번호 */
u64 dev:5; /* PCI Device 번호 */
u64 bus:8; /* PCI Bus 번호 */
u64 pkg:8; /* CPU Package ID */
u64 reserved:40;
} __packed;
/* Feature 드라이버가 사용하는 TPMI API (include/linux/intel_tpmi.h) */
struct intel_tpmi_plat_info *tpmi_get_platform_data(
struct auxiliary_device *adev); /* 플랫폼 정보 반환 */
int tpmi_get_resource_count(
struct auxiliary_device *adev); /* MMIO 인스턴스 수 반환 */
struct resource *tpmi_get_resource_at_index(
struct auxiliary_device *adev,
int index); /* 인덱스별 MMIO resource 반환 */
int tpmi_get_feature_status(
struct auxiliary_device *adev,
int feature_id,
bool *read_blocked,
bool *write_blocked); /* 기능 잠금/비활성 상태 확인 */
RAPL over TPMI (intel_rapl_tpmi.c)
Meteor Lake+에서 RAPL 레지스터는 MSR 대신 TPMI MMIO를 통해 접근합니다. intel_rapl_tpmi 드라이버는 TPMI 코어에서 RAPL 기능(ID=0)의 MMIO 영역을 받아, 기존 intel_rapl_common의 powercap 프레임워크에 MMIO 백엔드로 등록합니다. 각 RAPL 도메인의 MMIO 블록 크기는 128바이트(TPMI_RAPL_DOMAIN_SIZE)이며, 각 Power Limit이 개별 레지스터를 가집니다(기존 MSR은 PL1+PL2가 하나의 64비트 MSR에 패킹).
등록 흐름: ① TPMI 코어가 PFS에서 TPMI_ID_RAPL=0 발견 → ② auxiliary 디바이스 intel_vsec.tpmi-rapl.N 생성 → ③ intel_rapl_tpmi probe → ④ tpmi_get_resource_at_index()로 MMIO 매핑 → ⑤ rapl_add_package()로 powercap zone 등록 → ⑥ /sys/class/powercap/intel-rapl:* 노출
/* intel_rapl_tpmi.c — MMIO 기반 RAPL 백엔드 */
/* TPMI RAPL MMIO 레지스터 오프셋 (MSR 주소 대신 MMIO 오프셋 사용) */
#define TPMI_RAPL_REG_HEADER 0x00
#define TPMI_RAPL_REG_UNIT 0x08 /* 에너지/전력/시간 단위 */
#define TPMI_RAPL_REG_PL1 0x10 /* Package Power Limit 1 */
#define TPMI_RAPL_REG_PL2 0x18 /* Package Power Limit 2 */
#define TPMI_RAPL_REG_PL4 0x20 /* Package Power Limit 4 */
#define TPMI_RAPL_REG_ENERGY_STATUS 0x28 /* 에너지 카운터 */
#define TPMI_RAPL_REG_PERF_STATUS 0x30 /* 성능 스로틀 상태 */
#define TPMI_RAPL_REG_POWER_INFO 0x38 /* TDP, min/max 전력 */
/* 디바이스별 RAPL TPMI 패키지 구조체 */
struct tpmi_rapl_package {
struct rapl_if_priv priv; /* RAPL 인터페이스 private */
struct intel_tpmi_plat_info *tpmi_info; /* TPMI 플랫폼 정보 */
struct rapl_package *rp; /* RAPL 패키지 포인터 */
void __iomem *base; /* MMIO 베이스 주소 */
};
/* MMIO 기반 읽기 — IPI 없이 직접 접근 */
static int tpmi_rapl_read_raw(int id, struct reg_action *ra)
{
ra->value = readq(base + ra->reg.mmio_offset);
ra->value &= ra->mask; /* 마스크 적용 */
return 0;
}
/* MMIO 기반 쓰기 — read-modify-write 패턴 */
static int tpmi_rapl_write_raw(int id, struct reg_action *ra)
{
u64 val;
val = readq(base + ra->reg.mmio_offset);
val &= ~ra->mask; /* 대상 비트 클리어 */
val |= ra->value & ra->mask; /* 새 값 삽입 */
writeq(val, base + ra->reg.mmio_offset);
return 0;
}
/* rapl_if_priv — intel_rapl_common에 TPMI 백엔드 등록 */
static struct rapl_if_priv tpmi_rapl_priv = {
.type = RAPL_IF_TPMI,
.read_raw = tpmi_rapl_read_raw,
.write_raw = tpmi_rapl_write_raw,
.control_type = NULL, /* powercap에서 설정 */
.reg_unit = { .mmio_offset = TPMI_RAPL_REG_UNIT },
.regs = { /* 도메인별 레지스터 매핑 */
[RAPL_DOMAIN_PACKAGE] = {
.pl1 = { .mmio_offset = TPMI_RAPL_REG_PL1 },
.pl2 = { .mmio_offset = TPMI_RAPL_REG_PL2 },
.pl4 = { .mmio_offset = TPMI_RAPL_REG_PL4 },
.energy = { .mmio_offset = TPMI_RAPL_REG_ENERGY_STATUS },
.info = { .mmio_offset = TPMI_RAPL_REG_POWER_INFO },
},
},
};
intel_rapl_common 프레임워크를 사용하므로, 사용자 공간에서는 기존과 동일한 /sys/class/powercap/intel-rapl:* 경로로 접근합니다. MSR→TPMI 전환은 커널 내부에서 투명하게 처리됩니다.SST (Speed Select Technology) over TPMI
Intel Speed Select Technology(SST)는 동일 CPU 내에서 코어별 차등 성능 프로파일을 제공합니다. Meteor Lake+에서 SST는 TPMI(Feature ID=5)를 통해 접근합니다.
| SST 기능 | 설명 | 사용 사례 |
|---|---|---|
| SST-PP | Performance Profile — 미리 정의된 주파수/TDP 프로파일 전환 | 워크로드에 따라 코어 수 vs 주파수 트레이드오프 |
| SST-BF | Base Frequency — 특정 코어의 기본 주파수를 상향 | 지연시간에 민감한 코어에 높은 보장 주파수 할당 |
| SST-TF | Turbo Frequency — 특정 코어에 터보 주파수 우선 배분 | 고성능 요구 스레드에 터보 주파수 집중 |
| SST-CP | Core Power — 코어별 전력 우선순위 설정 | 중요 코어에 전력 예산 우선 배정 |
# intel-speed-select CLI 도구로 SST 상태 확인
intel-speed-select --info
intel-speed-select perf-profile info # SST-PP 프로파일 정보
intel-speed-select base-freq info # SST-BF 지원 코어 확인
intel-speed-select turbo-freq info # SST-TF 상태
intel-speed-select core-power info # SST-CP 우선순위
# SST-CP로 특정 코어에 높은 우선순위 부여
intel-speed-select core-power assoc --clos 0 --core 0,1,2,3 # 고성능 그룹
intel-speed-select core-power assoc --clos 3 --core 4,5,6,7 # 저전력 그룹
Uncore 주파수 제어 over TPMI
TPMI 이전에는 Uncore 주파수가 패키지/다이 단위로만 제어 가능했습니다. TPMI(Feature ID=2)는 패브릭 클러스터(fabric cluster) 단위의 세밀한 Uncore 주파수 제어를 지원합니다.
PLR (Performance Limit Reasons) over TPMI
PLR(Feature ID=8)은 CPU 성능이 제한(스로틀링)되는 원인을 실시간으로 보고합니다. TPMI를 통해 debugfs에 노출되며, 성능 문제 진단에 활용됩니다.
# PLR 상태 확인 (debugfs)
ls /sys/kernel/debug/tpmi-plr/
# die0/ die1/ ...
cat /sys/kernel/debug/tpmi-plr/die0/status
# 각 비트가 스로틀링 원인을 나타냄:
# - thermal: 열 제한
# - power_limit_pl1: PL1(장기 전력) 초과
# - power_limit_pl2: PL2(단기 전력) 초과
# - electrical_design_point: 전류 한계 도달
# - turbo_transition_attenuation: 터보 전환 감쇠
# - prochot: 외부 PROCHOT# 신호
# PLR 스티키 비트 클리어 (해당 파일에 0 쓰기)
echo 0 > /sys/kernel/debug/tpmi-plr/die0/status
TPMI 커널 설정
# TPMI 관련 Kconfig 옵션
CONFIG_INTEL_VSEC=m # Intel Vendor Specific Extended Capabilities (필수)
CONFIG_INTEL_TPMI=m # TPMI 코어 드라이버
CONFIG_INTEL_RAPL_TPMI=m # RAPL over TPMI 백엔드
CONFIG_INTEL_UNCORE_FREQ_TPMI=m # Uncore 주파수 제어 over TPMI
CONFIG_INTEL_SPEED_SELECT_INTERFACE=m # SST over TPMI
# 로드된 TPMI 모듈 확인
lsmod | grep tpmi
# intel_rapl_tpmi 16384 0
# intel_uncore_freq_tpmi 16384 0
# isst_tpmi 20480 0
# intel_tpmi 24576 3 intel_rapl_tpmi,intel_uncore_freq_tpmi,isst_tpmi
# intel_vsec 16384 1 intel_tpmi
# TPMI 디바이스 확인 (PCI VSEC)
lspci -d 8086: -vvv | grep -A5 "Vendor Specific"
TPMI 소스 트리 구조
| 파일 | 역할 |
|---|---|
include/linux/intel_tpmi.h | TPMI API 헤더 — Feature ID 상수, 플랫폼 정보 구조체, 헬퍼 함수 |
drivers/platform/x86/intel/vsec.c | PCI VSEC 드라이버 — TPMI 타입 감지 및 코어 디바이스 생성 |
drivers/platform/x86/intel/tpmi.c | TPMI 코어 — PFS 파싱, MMIO 매핑, auxiliary 디바이스 생성, debugfs (커널 6.13+에서 vsec_tpmi.c로 개명) |
drivers/powercap/intel_rapl_tpmi.c | RAPL TPMI 백엔드 — MMIO 기반 에너지/전력 레지스터 접근 |
drivers/platform/x86/intel/uncore-frequency/ | Uncore 주파수 제어 (TPMI + MSR 백엔드) |
drivers/platform/x86/intel/speed_select_if/ | SST 인터페이스 (TPMI + MMIO + MSR 백엔드) |
TPMI debugfs 인터페이스
TPMI 코어 드라이버는 debugfs를 통해 PFS 테이블 덤프와 Feature별 MMIO 원시 읽기/쓰기를 제공합니다. 주로 디버깅과 펌웨어 설정 확인에 사용됩니다.
# TPMI debugfs 구조
/sys/kernel/debug/tpmi-<N>/
├── pfs_dump # PFS 테이블 전체 엔트리 출력
├── tpmi-id-<feature_id>/
│ ├── mem_dump # Feature MMIO 영역 원시 덤프 (읽기 전용)
│ └── mem_write # 특정 오프셋에 MMIO 쓰기 (디버그용)
└── ...
# PFS 엔트리 확인 (어떤 PM 기능이 지원되는지)
cat /sys/kernel/debug/tpmi-0/pfs_dump
# RAPL MMIO 레지스터 원시 값 확인
cat /sys/kernel/debug/tpmi-0/tpmi-id-0/mem_dump
TPMI 커널 머지 타임라인
| 커널 버전 | TPMI 마일스톤 |
|---|---|
| 6.3 | TPMI 기본 열거 드라이버 병합 (tpmi.c) |
| 6.4 | RAPL TPMI 드라이버 (intel_rapl_tpmi.c) 병합 |
| 6.5 | Uncore 주파수 TPMI 지원, SST via TPMI |
| 6.5~6.6 | TPMI debugfs, 기능 잠금 상태 인터페이스 |
| 6.6+ | CPU 토폴로지/도메인 매핑, 클러스터 레벨 제어 |
| 6.13 | 드라이버 tpmi.c → vsec_tpmi.c 개명, Clearwater Forest ID 추가 |
AMD RAPL 지원
AMD는 Zen 아키텍처(Family 17h, Ryzen 1000/EPYC 7001) 이후로 RAPL 호환 MSR을 제공합니다. 커널 intel_rapl_msr 드라이버가 AMD CPU도 지원하여 동일한 powercap sysfs 인터페이스로 접근 가능합니다.
| 항목 | Intel RAPL | AMD RAPL |
|---|---|---|
| 지원 시작 | Sandy Bridge (2세대, 2011) | Zen (Family 17h, 2017) |
| 도메인 | package, core, uncore, dram, psys | package, core (Zen 2+에서 확장) |
| MSR 주소 | 606h, 610h, 611h, 619h, 641h 등 | C001_0299h (core), C001_029Ah (pkg) 등 |
| 전력 제한 쓰기 | PL1/PL2 쓰기 가능 | 읽기 전용 (에너지 측정만, 전력 제한 설정 불가) |
| 커널 드라이버 | intel_rapl_msr / intel_rapl_tpmi | intel_rapl_msr (AMD 지원 포함) |
| perf 이벤트 | power/energy-pkg,cores,ram/ | power/energy-pkg,cores/ |
amd_pstate 드라이버의 EPP(Energy Performance Preference)를 통해 관리합니다.perf 전력 이벤트 및 모니터링 도구
# RAPL 전력 측정 (perf) — 5초간 에너지 소비 측정
perf stat -e power/energy-pkg/,power/energy-cores/,power/energy-ram/ sleep 5
# 특정 프로세스의 전력 소비 프로파일링
perf stat -e power/energy-pkg/,power/energy-cores/ -- make -j$(nproc)
# turbostat — 실시간 전력/주파수/온도 모니터링
turbostat --show Package,Core,CPU,Avg_MHz,Busy%,PkgWatt,CorWatt,RAMWatt --interval 1
# powertop — 전력 소비 분석 + 절전 추천
powertop --auto-tune # 자동 절전 최적화 적용
powertop --csv=report.csv --time=30 # 30초 측정 후 CSV 리포트
# powercap 에너지 직접 읽기 (커스텀 스크립트용)
E1=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)
sleep 5
E2=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)
echo "5초간 소비: $(( (E2 - E1) / 1000000 )) J, 평균: $(( (E2 - E1) / 5000000 )) W"
실전 예제: PL1 제한 효과 측정
전력 제한(PL1)을 적용했을 때 성능과 전력의 트레이드오프를 실제로 측정해봅니다.
예제 1: PL1 제한 전후 벤치마크
#!/bin/bash
# PL1 제한 효과 비교 스크립트
# 1. 기본 PL1 확인 및 저장
RAPL_PATH="/sys/class/powercap/intel-rapl:0"
ORIG_PL1=$(cat ${RAPL_PATH}/constraint_0_power_limit_uw)
echo "원래 PL1: $(( ORIG_PL1 / 1000000 )) W"
# 2. 제한 없음 (기본값) 테스트
echo "=== 기본 설정 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy
# 3. PL1 25W로 제한
echo 25000000 > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "=== PL1 25W 제한 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy
# 4. PL1 15W로 강제 제한
echo 15000000 > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "=== PL1 15W 제한 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy
# 5. 원래 설정 복원
echo ${ORIG_PL1} > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "PL1 복원 완료"
예상 결과:
| PL1 설정 | Package 에너지 | 성능 (작업 완료) | 평균 전력 | 효율 |
|---|---|---|---|---|
| 기본 (45W) | ~1350 J | 100% (기준) | 45W | 1.0× |
| 25W 제한 | ~900 J | ~85% | 25W | 1.4× |
| 15W 제한 | ~750 J | ~65% | 15W | 1.6× |
예제 2: 프로그램별 에너지 프로파일링
# 컴파일 vs 압축 vs 암호화 — 에너지 소비 비교
# 컴파일 (CPU intensive)
perf stat -e power/energy-pkg/,power/energy-cores/ -- \
make -j$(nproc) clean all
# 압축 (메모리 대역폭 intensive)
perf stat -e power/energy-pkg/,power/energy-ram/ -- \
tar -czf archive.tar.gz /usr/share/doc
# 암호화 (CPU + 일부 메모리)
perf stat -e power/energy-pkg/,power/energy-cores/ -- \
openssl enc -aes-256-cbc -in largefile -out largefile.enc -k password
# 결과 비교 예시:
# 컴파일: Package 2500J, Cores 1800J, RAM 200J → CPU 중심
# 압축: Package 1200J, Cores 600J, RAM 400J → 메모리 대역폭 비중 큼
# 암호화: Package 1800J, Cores 1500J, RAM 100J → CPU 집약적
예제 3: turbostat으로 실시간 전력 추적
# turbostat으로 PL1 제한 효과 실시간 관찰
# 터미널 1: turbostat 실행
sudo turbostat --show Package,Core,CPU,Avg_MHz,Busy%,PkgWatt,CorWatt,GFXWatt --interval 1
# 터미널 2: 부하 적용 후 PL1 변경
stress-ng --cpu 8 --timeout 120s &
sleep 30
echo 25000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
# → turbostat에서 PkgWatt가 즉시 25W 이하로 떨어지는 것 확인
# → Avg_MHz도 함께 감소 (스로틀링)
sleep 30
echo ${ORIG_PL1} > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
# → PkgWatt와 Avg_MHz가 원래대로 복구
RAPL 정확도·보안·제한사항
energy_uj 및 perf power 이벤트 접근에 CAP_SYS_RAWIO 또는 root 권한이 필요하도록 변경되었습니다.| 항목 | 설명 |
|---|---|
| 에너지 해상도 | 약 15.3μJ (2-16 J × 에너지 단위). 실제 정확도는 ±5~10% 수준으로 절대 전력 측정보다는 상대 비교에 적합 |
| 카운터 오버플로 | 32비트 에너지 카운터는 max_energy_range_uj 도달 시 0으로 랩어라운드. 고부하 서버에서 ~60초마다 발생 가능 — 폴링 간격 주의 |
| 접근 권한 (5.10+) | /sys/class/powercap/*/energy_uj: root 또는 CAP_SYS_RAWIO. perf power 이벤트: perf_event_paranoid ≤ 0 또는 CAP_PERFMON |
| 가상화 환경 | VM에서는 RAPL MSR 접근이 차단됨 (hypervisor가 trap). KVM -cpu host로 패스스루 가능하나 보안상 비권장 |
| 컨테이너 | cgroup v2의 perf 이벤트 네임스페이스와 결합하여 컨테이너별 에너지 측정 가능 (Kepler 프로젝트 등 활용) |
# 현재 perf 접근 권한 확인
cat /proc/sys/kernel/perf_event_paranoid
# 4: 모든 perf 이벤트 제한 (기본값, 일부 배포판)
# 2: 커널 이벤트 제한 (기본값)
# 1: CPU 이벤트 제한
# 0: 제한 없음
# -1: 모든 접근 허용
# RAPL 에너지 읽기가 Permission denied인 경우
sudo sysctl kernel.perf_event_paranoid=0 # 임시 해제 (재부팅 시 초기화)
# 오버플로 범위 확인
cat /sys/class/powercap/intel-rapl:0/max_energy_range_uj
# 예: 262143328850 (≈262 kJ, 150W 시 ~29분마다 오버플로)