웹사이트 검색

Linux에서 프로파일링 도구 Gprof를 설치하고 사용하는 방법


이 페이지에서

  1. Gprof란 무엇입니까?
  2. Gprof 다운로드 및 설치
  3. Gprof 사용법

테스팅이 소프트웨어 개발 프로세스의 필수 요소이자 가장 중요한 측면 중 하나라는 데는 의심의 여지가 없습니다. 그리고 테스트는 단순히 버그에 대한 코드를 테스트하는 것을 의미하지 않습니다. 물론 아무도 자신의 소프트웨어에 버그가 있는 것을 원하지 않기 때문에 버그 감지가 중요합니다. 요즘에는 코드의 성능도 똑같이 중요합니다.

마지막 비트까지 세분화하면 성능 테스트는 특정 코드 조각(예: 함수)이 소비하는 시간을 효과적으로 테스트합니다. 일반적으로 기능 또는 기능 그룹은 소프트웨어의 많은 기능 중 하나에 해당할 수 있습니다. 따라서 성능 테스트를 통해 코드에서 이러한 기능의 성능을 향상시킬 수 있다면 소프트웨어의 전반적인 성능이 향상됩니다.

C, Pascal 또는 Fortran77 프로그래밍 언어로 코드를 작성하고 Linux를 개발 플랫폼으로 사용하는 프로그래머라면 코드의 성능을 확인할 수 있는 강력한 도구인 도구가 있다는 사실에 기뻐할 것입니다. 문제는 Gprof입니다. 이 자습서에서는 이 도구를 다운로드, 설치 및 사용하는 방법에 대해 자세히 설명합니다.

계속 진행하기 전에 이 튜토리얼에 언급된 모든 예제와 지침은 Ubuntu 14.04LTS에서 테스트되었으며 사용된 Gprof 버전은 2.24입니다.

그프로프란?

그렇다면 Gprof는 정확히 무엇입니까? 도구 공식 문서에 따르면 사용자에게 C, Pascal 또는 Fortran77 프로그램의 실행 프로필을 제공합니다. Gprof가 기본적으로 수행하는 작업은 각 루틴 또는 기능에 소요되는 시간을 계산하는 것입니다. "다음으로 이 시간은 호출 그래프의 가장자리를 따라 전파됩니다. 주기가 발견되고 주기의 시간을 공유하기 위해 주기에 대한 호출이 이루어집니다."

이 모든 것이 이 시점에서 약간 혼란스럽게 들리더라도(특히 따옴표로 묶인 부분) 걱정하지 말고 예제를 통해 명확하게 설명하십시오. 계속 읽어보세요.

Gprof 다운로드 및 설치

먼저 도구가 시스템에 이미 설치되어 있는지 확인하십시오. 이렇게 하려면 터미널에서 다음 명령을 실행하기만 하면 됩니다.

$ gprof

다음과 같은 오류가 발생하는 경우:

$ a.out: No such file or directory

그러면 도구가 이미 설치되어 있음을 의미합니다. 그렇지 않으면 다음 명령을 사용하여 설치할 수 있습니다.

$ apt-get install binutils

Gprof 사용법

말할 필요도 없이 Gprof와 같은 도구를 이해하는 가장 좋은 방법은 실용적인 예를 보는 것입니다. 따라서 Gprof를 통해 프로파일링하는 C 언어 프로그램으로 시작하는 것이 좋습니다. 프로그램은 다음과 같습니다.

//test_gprof.c

#include<stdio.h>

void func4(void)
{
    printf("\n Inside func4() \n");
    for(int count=0;count<=0XFFFF;count++);
}

void func3(void)
{
    printf("\n Inside func3() \n");
    for(int count=0;count<=0XFFFFFFF;count++);
}

void func2(void)
{
    printf("\n Inside func2() \n");

    for(int count=0;count<=0XFFF;count++);

    func3();
}

void func1(void)
{
    printf("\n Inside func1() \n");
    for(int count=0;count<=0XFFFFFF;count++);

    func2();
}

int main(void)
{
    printf("\n main() starts...\n");
    for(int count=0;count<=0XFFFFF;count++);

    func1();
    func4();
    printf("\n main() ends...\n");

    return 0;
}

위에 표시된 코드(test_gprof.c)는 Gprof를 설명하기 위해 특별히 작성되었으며 실제 프로젝트에서 가져온 것이 아닙니다.

이제 다음 단계는 gcc를 사용하여 이 코드를 컴파일하는 것입니다. 이상적으로는 다음 명령을 사용하여 위의 코드를 컴파일했을 것입니다.

$ gcc -Wall -std=c99 test_gprof.c -o test_gprof

그러나 Gprof를 사용하여 코드를 프로파일링해야 하므로 gcc 컴파일러에서 제공하는 -pg 명령줄 옵션을 사용해야 합니다. 따라서 명령은 다음과 같이 됩니다.

$ gcc -Wall -std=c99 -pg test_gprof.c -o test_gprof

gccs 매뉴얼 페이지를 살펴보면 -pg 옵션에 대한 설명이 다음과 같습니다.

"분석 프로그램 gprof에 적합한 프로필 정보를 작성하기 위한 추가 코드를 생성합니다. 데이터를 원하는 소스 파일을 컴파일할 때 이 옵션을 사용해야 하며, 링크할 때도 사용해야 합니다."

이제 위 명령으로 돌아가 성공적으로 실행된 후 출력에 test_gprof라는 이름의 바이너리를 생성합니다. 다음 단계는 해당 실행 파일을 시작하는 것입니다. 제 경우에 바이너리를 시작한 방법은 다음과 같습니다.

$ ./test_gprof

명령이 실행되면 gmon.out이라는 파일이 현재 작업 디렉토리에 생성되는 것을 볼 수 있습니다.

$ ls gmon*
gmon.out


Gprof 도구가 사람이 읽을 수 있는 프로파일링 데이터를 생성하는 데 필요한 모든 정보가 포함된 파일입니다. 이제 다음과 같은 방식으로 Gprof 도구를 사용하십시오.

$ gprof test_gprof gmon.out > profile-data.txt

기본적으로 이 명령의 일반 구문은 다음과 같습니다.

$ gprof [executable-name] gmon.out > [name-of-file-that-will-contain-profiling-data]

이제 profile-data.txt 파일에 포함된 정보를 보기 전에 Gprof가 생성하는 사람이 읽을 수 있는 출력이 플랫 프로필과 호출 그래프의 두 부분으로 나뉜다는 점을 언급할 가치가 있습니다. 다음은 Gprof의 매뉴얼 페이지에서 이 두 섹션의 정보에 대해 설명하는 내용입니다.

"플랫 프로필은 프로그램이 각 기능에 소요된 시간과 해당 기능이 호출된 횟수를 보여줍니다. 어떤 기능이 대부분의 사이클을 소모하는지 알고 싶다면 여기에 간략하게 명시되어 있습니다."

"호출 그래프는 각 함수에 대해 호출한 함수, 호출한 다른 함수 및 횟수를 보여줍니다. 또한 각 함수의 서브루틴에서 소요된 시간의 추정치도 있습니다. 이를 통해 많은 시간을 사용하는 함수 호출을 제거할 수 있는 장소를 제안합니다."

이 정보로 무장하면 이제 프로파일링 출력 파일(제 경우에는 profile-data.txt)에 있는 데이터를 더 잘 이해할 수 있습니다. 내 경우의 평면 프로필은 다음과 같습니다.

Flat profile:

Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
96.43 0.81 0.81 1 810.00 810.00 func3
3.57 0.84 0.03 1 30.00 840.00 func1
0.00 0.84 0.00 1 0.00 810.00 func2
0.00 0.84 0.00 1 0.00 0.00 func4

각 필드의 의미는 다음과 같습니다.

계속해서 제 경우의 호출 그래프는 다음과 같습니다.

Call graph (explanation follows)


granularity: each sample hit covers 4 byte(s) for 1.19% of 0.84 seconds

index % time self children called name
0.03 0.81 1/1 main [2]
[1] 100.0 0.03 0.81 1 func1 [1]
0.00 0.81 1/1 func2 [3]
-----------------------------------------------
<spontaneous>
[2] 100.0 0.00 0.84 main [2]
0.03 0.81 1/1 func1 [1]
0.00 0.00 1/1 func4 [5]
-----------------------------------------------
0.00 0.81 1/1 func1 [1]
[3] 96.4 0.00 0.81 1 func2 [3]
0.81 0.00 1/1 func3 [4]
-----------------------------------------------
0.81 0.00 1/1 func2 [3]
[4] 96.4 0.81 0.00 1 func3 [4]
-----------------------------------------------
0.00 0.00 1/1 main [2]
[5] 0.0 0.00 0.00 1 func4 [5]

다음 스크린샷은 호출 그래프에 포함된 정보를 설명합니다.

위 스크린샷의 출처가 궁금하다면 이 모든 정보가 평면 프로필 및 호출 그래프를 포함한 프로파일링 정보가 포함된 출력 파일에 있음을 알려드립니다. 이 정보를 출력에서 생략하려면 Gprof에서 제공하는 -b 옵션을 사용할 수 있습니다.

결론

말할 필요도 없이 Gprof는 많은 기능을 제공하므로 여기에서 표면을 긁어봤습니다(매뉴얼 페이지 참조). 그러나 여기에서 다룬 내용은 시작하기에 충분해야 합니다. 이미 Gprof를 사용 중이고 이 도구와 관련된 내용을 여기에 있는 모든 사람과 공유하고 싶다면 아래에 의견을 남겨주세요.