title: 카운터/모니터링
date: 2025-06-26
category: arch
tags: [PMU, Performance Counters, PEBS, perf_event, profiling, monitoring, hardware counters]
카운터/모니터링 (PMU, Performance Counters, PEBS)
개요
프로세서 모니터링 유닛(PMU)의 핵심 구성인 성능 모니터링 카운터(Performance Monitoring Counters, PMC)는 현대 마이크로프로세서에 내장된 특수 레지스터로, CPU의 다양한 하드웨어 이벤트 발생 횟수를 직접 기록한다. 이를 통해 소프트웨어 프로파일러가 개입하지 않고도 캐시 미스, 분기 예측 실패, 파이프라인 스톨, 명령어 실행 수 등 저수준 성능 지표를 낮은 오버헤드로 수집할 수 있다. PMU 하드웨어는 프로파일링, 벤치마킹, 실시간 모니터링, 디버깅 등 다양한 활용 영역에서 핵심적인 역할을 하며, Linux의 perf, Intel VTune, AMD uProf 등 주요 성능 분석 도구의 기반 기술로 사용된다.
PEBS(Processor Event-Based Sampling)는 Intel 아키텍처에서 도입된 샘플링 기반 프로파일링 메커니즘으로, 하드웨어 카운터가 지정된 임계값에 도달하면 자동으로 프로세서 상태(IP, 레지스터, 스택 등)를 기록한다. PEBS는 기존 인터럽트 기반 샘플링의 '스키드(skid)' 문제, 즉 이벤트 발생 시점과 기록 시점 사이의 명령어 실행 격차를 근본적으로 줄여 샘플링 정밀도를 크게 향상시킨다.
핵심 개념
프로세서 모니터링 카운터 (PMC)
PMC는 CPU 파이프라인의 다양한 위치에서 하드웨어 이벤트를 카운팅하는 64비트 프로그래밍 가능 레지스터다. 각 카운터는 이벤트 유형(config), 카운팅 모드(이벤트 카운트 또는 샘플링), 필터링 조건(커널/유저 모드 제외 등)을 독립적으로 설정할 수 있다.
| 특성 | 설명 |
|---|---|
| 레지스터 수 | 아키텍처마다 다름 (Intel: 4~8개 기본, 추가 via 논리적 PMC; ARM: 6개 기본) |
| 카운팅 모드 | counting (누적 합산) / sampling (오버플로우 시 샘플 기록) |
| 이벤트 유형 | 하드웨어 카운터, 소프트웨어 카운터, 캐시 이벤트, 트레이스포인트 등 |
| 프로그래밍 | perf_event_open() 시스템 호출, MSR/PMU 레지스터 직접 기록 |
하드웨어 성능 카운터 이벤트
현대 프로세서에서 측정 가능한 대표적인 하드웨어 이벤트:
| 이벤트 카테고리 | 예시 이벤트 | 설명 |
|---|---|---|
| CPU 사이클 | CPU_CYCLES, REF_CPU_CYCLES | 전체 클럭 사이클 (frequency scaling 영향 여부 선택) |
| 명령어 | INSTRUCTIONS | 완료된(retired) 명령어 수 |
| 캐시 | CACHE_REFERENCES, CACHE_MISSES | LLC 접근/미스 횟수 |
| 분기 | BRANCH_INSTRUCTIONS, BRANCH_MISSES | 분기 명령어 실행/예측 실패 |
| 파이프라인 스톨 | STALLED_CYCLES_FRONTEND, STALLED_CYCLES_BACKEND | 프론트엔드/백엔드 스톨 사이클 |
| 메모리 | LLC_LOAD_MISSES, LLC_STORE_MISSES | LLC 로드/스토어 미스 |
| TLB | DTLB_LOAD_MISSES, ITLB_MISSES | 데이터/명령어 TLB 미스 |
Processor Event-Based Sampling (PEBS)
PEBS는 Intel Nehalem(2008) 이후 프로세서에서 지원되는 하드웨어 기반 샘플링 메커니즘이다. 기존의 NMI(Non-Maskable Interrupt) 기반 샘플링과 비교하여 정밀도가 크게 향상된다.
| 특성 | 인터럽트 기반 샘플링 | PEBS |
|---|---|---|
| 기록 시점 | 인터럽트 발생 후 커널이 개입하여 기록 | 이벤트 발생 즉시 하드웨어가 자동 기록 |
| 스키드(skid) | 다수의 명령어 실행 격차 발생 | 거의 0 (정밀한 IP 기록) |
| 기록 대상 | IP, 타임스탬프, 콜체인 | IP, 레지스터(ALL/selected), 스택, 타임스탬프, LBR |
| 성능 오버헤드 | 높음 (인터럽트 처리 비용) | 매우 낮음 (하드웨어 자동 기록) |
| 사용 사례 | 일반 프로파일링 | 정밀한 hotspot 분석, 메모리 접근 패턴 분석 |
perf_event 인터페이스
Linux 커널의 perf_event_open()은 PMU 카운터에 접근하기 위한 표준 시스템 호출 인터페이스다. 사용자 공간 도구(perf, VTune, uProf 등)는 이 시스템 호출을 통해 카운터를 구성하고 데이터를 수집한다.
perf_event_open() 호출 구조:
┌──────────────────────────────────────────────┐
│ struct perf_event_attr │
│ ├─ type: 이벤트 유형 (HW/SW/TRACEPOINT/RAW) │
│ ├─ config: 이벤트 상세 설정 │
│ ├─ sample_period/freq: 샘플링 주기 │
│ ├─ sample_type: 기록할 데이터 종류 │
│ ├─ disabled: 초기 비활성화 여부 │
│ ├─ inherit: 자식 프로세스 상속 여부 │
│ ├─ pinned: PMU에 고정 여부 │
│ ├─ exclude_user/kernel/hv: 모드별 제외 │
│ └─ precise_ip: 스키드 제어 (0~3) │
└──────────────────────────────────────────────┘
비교/분석
x86 vs ARM PMU 비교
| 항목 | x86 (Intel/AMD) | ARM (AArch64) |
|---|---|---|
| 기본 카운터 수 | 4개 (Intel), 4~6개 (AMD) | 6개 (모델별 상이) |
| 논리적 PMC | HyperThreading 시 코어당 2배 | 없음 (SMT 지원 시 확장) |
| 샘플링 메커니즘 | PEBS (Intel), IBS (AMD) | SPE (Statistical Profiling Extension) |
| 이벤트 정의 | MSR (Model Specific Registers) | PMEVTYPERn_EL0 레지스터 |
| 시스템 호출 | perf_event_open() | perf_event_open() (동일) |
| 인터페이스 도구 | perf, VTune, uProf | perf, Streamline |
AMD IBS (Instruction-Based Sampling) vs Intel PEBS
| 항목 | Intel PEBS | AMD IBS |
|---|---|---|
| 샘플링 단위 | 이벤트 기반 (카운터 오버플로우) | 명령어 기반 (일정 간격 명령어 샘플링) |
| 정밀도 | 높음 (스키드 ≈ 0) | 매우 높음 (명령어 단위 정확한 기록) |
| 지원 이벤트 | 이벤트별 제한적 | 모든 명령어에서 동작 |
| 기록 대상 | IP, 레지스터, 스택, LBR | IP, 레지스터, 타임스탬프, 데이터 주소 |
| 하드웨어 지원 | Nehalem(2008)~ | Family 10h(2007)~ |
주요 프로파일링 도구 비교
| 도구 | 플랫폼 | 주요 기능 | 인터페이스 |
|---|---|---|---|
| Linux perf | Linux | 카운팅, 샘플링, 이벤트 추적, 커널 분석 | perf_event_open() |
| Intel VTune | Linux/Windows | hotspot 분석, 메모리 접근 분석, 멀티스레드 분석 | perf_event_open(), 전용 드라이버 |
| AMD uProf | Linux/Windows | CPI, 메모리 대역폭, 전력 분석 | perf_event_open() |
| OProfile | Linux | 시스템 전역 프로파일링 | perf_event_open(), 하드웨어 인터럽트 |
| PAPI | Linux/Windows | 이동 가능한 성능 인터페이스 | perf_event_open(), 하드웨어 레지스터 |
동작 원리
카운팅 모드 동작
카운팅 모드에서는 설정된 이벤트가 발생할 때마다 카운터 레지스터가 1씩 증가한다. 이벤트가 누적되면 read() 시스템 호출을 통해 값을 읽거나, 그룹 내 여러 카운터 값을 동시에 읽어 비율을 계산할 수 있다.
카운팅 모드 흐름:
┌────────────────────┐
│ perf_event_open() │ 카운터 설정
└─────────┬──────────┘
▼
┌────────────────────┐
│ 이벤트 발생 대기 │
└─────────┬──────────┘
▼
┌────────────────────┐
│ 이벤트 감지 │ 하드웨어가 자동 카운트 증가
└─────────┬──────────┘
▼
┌────────────────────┐
│ read() 호출 시 │ 카운트 값 반환
│ 누적 값 반환 │
└────────────────────┘
샘플링 모드 동작 (PEBS 포함)
샘플링 모드에서는 카운터가 sample_period 값에 도달할 때마다 오버플로우가 발생하고, 이 시점의 프로세서 상태(IP, 레지스터, 스택 등)가 메모리의 링 버퍼(ring buffer)에 자동으로 기록된다. PEBS를 사용하면 하드웨어가 직접 기록하여 스키드를 최소화한다.
PEBS 샘플링 모드 흐름:
┌────────────────────┐
│ perf_event_open() │ sample_period 설정, precise_ip=3
└─────────┬──────────┘
▼
┌────────────────────┐
│ 이벤트 카운팅 │
└─────────┬──────────┘
▼
┌────────────────────┐
│ 카운터 = period? │ No → 계속 카운팅
└─────────┬──────────┘
▼ Yes
┌────────────────────┐
│ PEBS 하드웨어 │ IP, 레지스터, 스택 자동 기록
│ 기록 수행 │ (스키드 ≈ 0)
└─────────┬──────────┘
▼
┌────────────────────┐
│ mmap() 링 버퍼 │ 사용자 공간에서 샘플 읽기
│ 접근 가능 │
└────────────────────┘
이벤트 그룹핑 (Event Grouping)
여러 이벤트를 동시에 측정할 때, 이벤트를 그룹으로 묶으면 동일한 명령어 세트에 대해 모든 카운터가 동시에 기록되므로 정확한 비율 계산이 가능하다.
이벤트 그룹 예시:
┌─────────────────────────────────────┐
│ 그룹 리더 (disabled=1, pinned=1) │
│ ├─ CPU_CYCLES │
│ └─ INSTRUCTIONS │
│ └─ (disabled=0) │
└─────────────────────────────────────┘
→ 모든 이벤트가 같은 실행 세트에 대해 카운팅됨
→ IPC = INSTRUCTIONS / CPU_CYCLES 계산 가능
precise_ip 레벨과 스키드
precise_ip 필드는 샘플링 정밀도를 제어하며, 값이 클수록 스키드가 줄어든다.
| precise_ip | 의미 | 스키드 수준 |
|---|---|---|
| 0 | SAMPLE_IP에 임의 스키드 허용 | 높음 |
| 1 | SAMPLE_IP에 상수 스키드 필요 | 중간 |
| 2 | SAMPLE_IP에 0 스키드 요청 | 낮음 |
| 3 | SAMPLE_IP에 0 스키드 필수 | 거의 0 (PEBS 사용) |
장단점
PMU/Performance Counters 장점
- 오버헤드 최소화: 하드웨어 카운터는 소프트웨어 개입 없이 카운팅하므로 성능 영향이 거의 없음
- 정밀한 측정: 소프트웨어 프로파일러로는 관찰 불가능한 저수준 이벤트 측정 가능
- 시스템 전역 모니터링: 특정 프로세스뿐 아니라 전체 시스템의 성능 지표 수집 가능
- 실시간 분석: 오버헤드가 낮아 프로덕션 환경에서도 안전하게 사용 가능
- 다양한 활용: 프로파일링, 벤치마킹, 디버깅, 전력 분석, 캐시 최적화 등 광범위
PMU/Performance Counters 단점
- 카운터 수 제한: 하드웨어적으로 지원되는 카운터 수가 제한적이어서, 많은 이벤트를 동시에 측정하려면 멀티플렉싱이 필요
- 아키텍처 의존성: 프로세서 제조사/모델에 따라 사용 가능한 이벤트와 의미가 다름
- 카운터 오버플로우: 64비트 카운터라도 매우 높은 이벤트 발생률에서는 오버플로우 가능
- 가상화 환경 제약: 가상 머신 환경에서는 하드웨어 카운터 접근이 제한될 수 있음
- 보안 문제: 하드웨어 성능 카운터를 악용한 사이드 채널 공격 가능성 (Spectre 등)
- 스키드 문제 (PEBS 미사용 시): 인터럽트 기반 샘플링에서는 이벤트 발생과 기록 사이에 명령어 실행 격차 발생
PEBS의 한계
- Intel 전용: AMD는 별도의 IBS(Instruction-Based Sampling) 메커니즘 사용
- 지원 이벤트 제한: 모든 하드웨어 이벤트가 PEBS를 지원하지 않음
- 설정 복잡성: precise_ip, sample_type, branch_sample_type 등 세밀한 설정 필요
- 메모리 사용: large PEBS 레코드 구성을 쓰면 추가 메모리 소비가 발생함
관련 기술
관련 하드웨어 기술
| 기술 | 설명 | 관련 카운터 |
|---|---|---|
| LBR (Last Branch Record) | 최근 분기 기록 하드웨어 버퍼 | PEBS와 함께 분기 프로파일링 |
| BTS (Branch Trace Store) | 분기 실행 경로 기록 | 분기 분석, 실행 경로 추적 |
| Intel PT (Processor Trace) | 명령어 실행 흐름 추적 | 극도의 정밀도가 필요한 디버깅 |
| AMD IBS | 명령어 기반 샘플링 | AMD 프로세서 정밀 프로파일링 |
| ARM SPE | 통계적 프로파일링 확장 | ARM 프로세서 샘플링 |
관련 소프트웨어/도구 기술
| 기술 | 설명 | 관련 카운터 |
|---|---|---|
| perf_event_open() | Linux PMU 인터페이스 시스템 호출 | 모든 Linux 성능 분석 도구의 기반 |
| perf (Linux) | Linux 기본 성능 분석 도구 | PMU 카운터, 샘플링, 이벤트 추적 |
| PAPI | 이동 가능한 성능 인터페이스 | 여러 아키텍처에서 일관된 카운터 접근 |
| libpfm4 | 성능 모니터링 라이브러리 | 이벤트 이름 → 하드웨어 설정 변환 |
| eBPF/perf_event | 커널 수준 이벤트 프로그래밍 | 커널 성능 이벤트 필터링/집계 |
참고 문헌
- Intel Corporation. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3B: System Programming Guide. Chapter 18: Performance Monitoring.
- AMD. BIOS and Kernel Developer's Guide (BKDG) for AMD Family 15h Models 30h-3Fh Processors. Chapter 2: Performance Monitor Counters.
- ARM Limited. ARM Architecture Reference Manual for A-profile Architecture. Chapter D10: Performance Analysis.
- Corbet, J. et al. Linux Device Drivers, 3rd Edition. O'Reilly Media, 2005. Chapter 10: Interrupt Handling.
- Intel Corporation. PEBS (Processor Event-Based Sampling) Technical Reference Manual.
- de Melo, A. The Linux Kernel: perf_event_open() Man Page. man7.org.
- Dowe, G. AMD Instruction-Based Sampling: A New Performance Analysis Technique. AMD Developer Central, 2007.
핵심 정리
-
프로세서 모니터링 카운터(PMC)는 CPU 하드웨어에 내장된 특수 레지스터로, 캐시 미스, 분기 예측 실패, 파이프라인 스톨 등 다양한 성능 이벤트를 오버헤드 없이 직접 카운팅한다. 이를 통해 소프트웨어 프로파일러의 개입 없이 저수준 성능 분석이 가능하다.
-
PEBS(Processor Event-Based Sampling)는 Intel 아키텍처의 하드웨어 기반 샘플링 메커니즘으로, 기존 인터럽트 기반 샘플링의 스키드(skid) 문제를 근본적으로 해결하여 거의 0에 가까운 스키드로 프로세서 상태를 기록한다. 이를 통해 정밀한 hotspot 분석이 가능해진다.
-
AMD의 IBS(Instruction-Based Sampling)는 명령어 단위로 샘플링하는 방식으로, 모든 명령어에서 동작하며 매우 높은 정밀도를 제공한다. Intel PEBS와는 접근 방식이 다르지만 동일한 목표인 정밀한 프로파일링을 추구한다.
-
Linux의 perf_event_open() 시스템 호출은 x86, ARM 등 다양한 아키텍처에서 공통으로 사용되는 PMU 인터페이스로, perf, VTune, uProf 등 주요 성능 분석 도구의 기반 기술로 사용된다. 이벤트 그룹핑, 샘플링, 카운팅 등 다양한 모드를 지원한다.
-
PMU/Performance Counters는 프로파일링, 벤치마킹, 실시간 모니터링, 디버깅, 전력 분석 등 광범위한 영역에서 활용되지만, 카운터 수 제한, 아키텍처 의존성, 보안 문제(사이드 채널 공격) 등의 한계도 존재한다. 이러한 한계를 극복하기 위해 이벤트 그룹핑, 멀티플렉싱, LBR, PT 등 보조 기술이 함께 발전해 왔다.