C++ Profiling | "성능 프로파일링" 가이드
이 글의 핵심
C++ Profiling에 대한 실전 가이드입니다. 개념부터 실무 활용까지 예제와 함께 상세히 설명합니다.
프로파일링이란?
프로그램 성능을 측정하고 병목 지점을 찾는 과정
// 측정 전: 어디가 느린지 모름
void process() {
step1();
step2();
step3();
}
// 측정 후: step2가 90% 시간 소요
기본 시간 측정
#include <chrono>
#include <iostream>
void measureTime() {
auto start = std::chrono::high_resolution_clock::now();
// 측정할 코드
for (int i = 0; i < 1000000; i++) {
// 작업
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "시간: " << duration.count() << "ms" << std::endl;
}
실전 예시
예시 1: 함수 프로파일링
#include <chrono>
#include <iostream>
class Timer {
std::chrono::time_point<std::chrono::high_resolution_clock> start;
std::string name;
public:
Timer(const std::string& n) : name(n) {
start = std::chrono::high_resolution_clock::now();
}
~Timer() {
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << name << ": " << duration.count() << "μs" << std::endl;
}
};
void slowFunction() {
Timer t("slowFunction");
// 작업
}
void fastFunction() {
Timer t("fastFunction");
// 작업
}
예시 2: gprof 사용
# 컴파일
g++ -pg program.cpp -o program
# 실행
./program
# 프로파일 생성
gprof program gprof.out > analysis.txt
예시 3: perf 사용
# 프로파일링
perf record ./program
# 결과 확인
perf report
# CPU 이벤트
perf stat ./program
예시 4: Valgrind Callgrind
# 프로파일링
valgrind --tool=callgrind ./program
# 결과 확인
kcachegrind callgrind.out.*
병목 지점 찾기
#include <map>
#include <chrono>
class Profiler {
struct Entry {
size_t count = 0;
long long totalTime = 0;
};
std::map<std::string, Entry> entries;
public:
void start(const std::string& name) {
// 시작 시간 기록
}
void end(const std::string& name) {
// 종료 시간 기록
}
void report() {
for (const auto& [name, entry] : entries) {
std::cout << name << ": "
<< entry.totalTime / entry.count << "μs"
<< " (" << entry.count << " calls)" << std::endl;
}
}
};
자주 발생하는 문제
문제 1: 측정 오버헤드
// ❌ 너무 자주 측정
for (int i = 0; i < 1000000; i++) {
auto start = std::chrono::high_resolution_clock::now();
doWork();
auto end = std::chrono::high_resolution_clock::now();
}
// ✅ 전체 측정
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 1000000; i++) {
doWork();
}
auto end = std::chrono::high_resolution_clock::now();
문제 2: 최적화 비활성화
// 디버그 빌드로 프로파일링 (느림)
g++ -g program.cpp
// ✅ 릴리스 빌드
g++ -O2 -g program.cpp
문제 3: 캐시 효과
// 첫 실행은 느림 (캐시 미스)
// 이후 실행은 빠름 (캐시 히트)
// ✅ 여러 번 실행 후 평균
문제 4: 조기 최적화
// ❌ 측정 전 최적화
void func() {
// 복잡한 최적화
}
// ✅ 측정 후 최적화
// 1. 프로파일링
// 2. 병목 지점 확인
// 3. 해당 부분만 최적화
프로파일링 도구
# gprof
g++ -pg program.cpp
./a.out
gprof a.out gmon.out
# perf (Linux)
perf record ./program
perf report
# Valgrind Callgrind
valgrind --tool=callgrind ./program
# Instruments (Mac)
instruments -t "Time Profiler" ./program
# Visual Studio Profiler (Windows)
FAQ
Q1: 프로파일링은 언제?
A:
- 성능 문제 발생
- 최적화 전
- 정기적 모니터링
Q2: 어떤 도구?
A:
- gprof: 기본
- perf: Linux 상세
- Valgrind: 정확
- Instruments: Mac
Q3: 측정 단위는?
A:
- 마이크로초 (μs)
- 밀리초 (ms)
- CPU 사이클
Q4: 최적화 순서는?
A:
- 측정
- 병목 찾기
- 최적화
- 재측정
Q5: 프로덕션 프로파일링?
A:
- 샘플링 프로파일러
- 낮은 오버헤드
- 통계 수집
Q6: 프로파일링 학습 리소스는?
A:
- “Optimized C++”
- perf 문서
- Valgrind 문서
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ Exception Performance | “예외 성능” 가이드
- C++ Cache Optimization | “캐시 최적화” 가이드
- C++ 프로파일링 | “어디가 느린지 모르겠어요” perf·gprof로 병목 찾기
관련 글
- C++ Cache Optimization |
- C++ Exception Performance |
- C++ Algorithm Sort |
- C++ Benchmarking |
- C++ Branch Prediction |