gprof 프로파일러 활용 가이드

gprof 성능 분석 도구

1. 개요

gprof는 프로파일링 결과를 분석하는 도구입니다. 이 도구는 복합적인 방식으로 프로그램의 실행 정보를 수집합니다. 첫째, 계측(instrumentation) 기법을 사용하여 컴파일 시점에 함수 시작 지점에 카운터를 삽입함으로써 각 함수의 호출 빈도와 호출 횟수를 기록합니다. 둘째, 샘플링(sampling) 기법을 활용하여 프로그램 실행 중 일정한 간격으로 프로그램 카운터를 확인하고, 분석 단계에서 해당 주소에 해당하는 함수를 찾아 함수별 소요 시간을 통계화합니다. gprof의 장단점은 다음과 같습니다: **장점:**
  • GNU 도구로 대부분의 리눅스 시스템에 기본 포함
  • 계측과 샘플링의 복합 방법 채택
**단점:**
  • 컴파일 옵션 필수:
    • gcc/cc로 컴파일 및 링크 시 -pg 옵션 사용 필요
    • ld로 링크 시 /lib/gcrt0.o를 crt0.o 대신 첫 번째 입력 파일로 지정
    • libc 디버깅 시 -lc_p 파라미터를 사용해야 함
  • 멀티스레드 프로그램 분석 시 메인 스레드 정보만 수집 가능

2. 사용 방법

2.1 프로그램 컴파일

gcc/cc를 사용하여 컴파일과 링크 시 -pg 옵션을 추가합니다. ld를 사용할 때는 /lib/gcrt0.o를 crt0.o 대신 첫 번째 입력 파일로 지정해야 합니다. libc 라이브러리 디버깅이 필요한 경우 -lc_p 파라미터를 사용하세요.

2.2 프로파일 데이터 생성

컴파일된 프로그램을 정상적으로 실행하면, 프로그램이 종료된 후 현재 디렉터리에 gmon.out 파일이 생성됩니다. 이 파일에 프로파일링 정보가 저장됩니다.

중요: 프로그램은 반드시 정상 종료(exit 호출 또는 main 함수에서 반환)해야 프로파일 데이터가 생성됩니다. 비정상 종료 시 데이터가 저장되지 않습니다.

기존에 같은 이름의 gmon.out 파일이 있으면 새 실행 결과로 덮어씌워집니다. 여러 번 테스트를 수행하려면 이전 파일을 다른 이름으로 백업하세요.

2.3 gprof로 결과 분석

명령어 형식:
gprof [options] [실행파일 [프로파일 데이터 파일...]] [> 출력파일]
주요 파라미터: symspec은 포함하거나 제외할 함수명을 지정하며, gdb의 브레이크포인트 설정 형식과 동일합니다. 출력 관련:
  • -A[symspec] 또는 --annotated-source[=symspec]: 소스 코드 연동. symspec을 지정하면 해당 함수만, 지정하지 않으면 전체 함수 연동
  • -I dirs 또는 --directory-path=dirs: 소스 파일 검색 디렉터리 추가 (GPROF_PATH 환경변수 변경도 가능)
  • -p[symspec] 또는 --flat-profile[=symspec]: 기본값. 호출 통계 정보 출력. symspec 지정 시 해당 함수만, 미지정 시 전체
  • -P[symspec] 또는 --no-flat-profile[=symspec]: 지정한 함수 제외
  • -q[symspec] 또는 --graph[=symspec]: 기본값. 함수 호출 관계 출력. symspec 지정 시 해당 함수만, 미지정 시 전체
  • -Q[symspec] 또는 --no-graph[=symspec]: 지정한 함수 제외
  • -b 또는 --brief: 파라미터 설명 출력 생략
분석 관련:
  • -a 또는 --no-static: static 함수非표시, 호출 횟수는 호출한 non-static 함수에 포함
  • -m num 또는 --min-count=num: 호출 횟수가 num 미만인 함수 표시 안 함
  • -z 또는 --display-unused-functions: 호출되지 않은 함수也表示

3. 사용 예제

테스트 코드 (profile_test.c):
#include <stdio.h>
#include <stdlib.h>

int calculate_sum(int limit)
{
    int result = 0;
    int counter = 0;
    while (counter++ < limit)
    {
        result += counter;
    }
    return result;
}

int process_data(int bound)
{
    int total = 0;
    int index = 0;
    while (index++ < bound)
    {
        total += index;
    }
    return total;
}

int main(int argc, char** argv)
{
    int loop_count;
    if (argc != 2)
    {
        printf("Usage: %s <Loop Count>\n", argv[0]);
        return 1;
    }
    
    loop_count = atoi(argv[1]);
    printf("Loop count = %d\n", loop_count);
    
    while (loop_count--)
    {
        calculate_sum(100000);
        process_data(400000);
    }
    
    return 0;
}
컴파일:
gcc -g -o profile_test profile_test.c -pg
실행:
./profile_test 10000
결과 분석:
gprof -b -A -p -q profile_test gmon.out > profiling_result.txt

4. 출력 정보 해석

필드 설명:
필드설명
% time 전체 실행 시간 중 해당 함수가 사용한 시간의 백분율
cumulative seconds 해당 함수와 위에 나열된 함수들의累计 실행 시간
self seconds 함수 자체의 실행 시간 (이 필드가 주요 정렬 기준)
calls 함수 호출 횟수 (프로파일링된 함수인 경우 표시)
self ms/call 호출每一次당 함수 자체에 소요되는 평균 시간(마이크로초)
total ms/call 호출每一次당 함수 및 하위 함수에 소요되는 평균 시간(마이크로초)
name 함수명 (보조 정렬 기준, 인덱스는 gprof 결과에서의 위치)

5. 시각화 도구

gprof 결과를 그래픽 형태로 시각화하려면 gprof2dot 도구를 사용할 수 있습니다. 설치:
apt-get install python3 graphviz
pip3 install --user gprof2dot
사용 방법:
gprof profile_test gmon.out | gprof2dot -s > output.dot
dot -Tpdf output.dot -o output.pdf
참고: gprof2dot 프로젝트

설치 시 발생 가능한 오류

pip3 설치 시 "Running pip install with root privileges" 경고가 나타나면 --user 옵션을 사용하는 것이 좋습니다.

6. 결론

gprof를 활용하면 프로그램의 성능 병목 지점을 효율적으로 파악할 수 있습니다. 프로파일링 결과를 분석하여 최적화가 필요한 부분을 식별하고 개선할 수 있습니다.

태그: linux GCC performance-profiling debugging profiling-tool

5월 28일 08:57에 게시됨