5.3. 프로파일 메모리 사용에 Valgrind 사용

Valgrind는 사용자 공간 바이너리에 대한 계측을 제공하는 프레임워크입니다. 이는 프로그램 성능을 프로파일링하고 분석하는데 사용할 수 있는 여러 도구와 함께 제공됩니다. 다음 부분에서 소개되는 도구는 메모리 사용 및 잘못된 메모리 할당 및 메모리 할당 해제와 같은 메모리 오류를 감지하는데 도움이 될 수 있는 분석을 제공합니다. 이러한 모든 것은 valgrind에 포함되어 다음과 같은 명령을 사용하여 실행할 수 있습니다:
valgrind --tool=toolname program
toolname을 사용하고자 하는 도구 이름 (메모리 프로파일링의 경우 memcheck, massif, cachegrind)으로 변경하고 program을 Valgrind으로 프로파일링하고자 하는 프로그램으로 변경합니다. Valgrind의 계측을 사용하면 프로그램이 평소보다 더 느리게 실행되는 원인이 될 수 있음에 유의합니다.
Valgrind 기능에 대한 개요는 3.5.3절. “Valgrind”에 설명되어 있습니다. Eclipse 용으로 사용 가능한 플러그인에 대한 정보를 포함한 자세한 내용은 http://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/에 있는 개발자 가이드에서 확인하실 수 있습니다. 부수적인 문서는 valgrind 패키지 설치 시 man valgrind 명령으로 확인하거나 다음의 위치에서 확인하실 수 있습니다:
  • /usr/share/doc/valgrind-version/valgrind_manual.pdf,
  • /usr/share/doc/valgrind-version/html/index.html.

5.3.1. Memcheck로 메모리 사용량 프로파일링

Memcheck는 기본 Valgrind 도구로 --tool=memcheck를 지정하지 않고 valgrind program으로 실행될 수 있습니다. 발생해서는 안되는 메모리 액세스, 정의되지 않거나 초기화되지 않은 값의 사용, 올바르지 않게 해제된 힙 메모리, 중복 포인터, 메모리 누수와 같은 감지 및 진단이 어려운 여러 메모리 오류를 감지하고 보고합니다. Memcheck를 사용하면 프로그램은 일반적으로 실행되는 것 보다 10-30 배 느리게 실행됩니다.
Memcheck는 감지된 문제의 종류에 따라 특정 오류를 반환합니다. 이러한 오류는 /usr/share/doc/valgrind-version/valgrind_manual.pdf에 포함된 Valgrind 문서에 자세히 설명되어 있습니다.
Memcheck는 이러한 오류를 보고만 할 수 있을 뿐 — 오류 발생을 방지할 수 없음에 유의합니다. 일반적으로 세그먼트 오류를 발생시킬 수 있는 방식으로 프로그램이 메모리에 액세스하는 경우 세스먼트 오류는 여전히 발생합니다. 하지만 Memcheck는 오류 직전에 오류 메세지를 기록합니다.
Memcheck는 검사 과정에 초점을 두는데 사용할 수 있는 명령행 옵션을 제공합니다. 이러한 옵션에는 다음과 같은 것이 있습니다:
--leak-check
활성화할 경우 Memcheck는 클라이언트 프로그램이 완료되면 메모리 누수를 검색합니다. 기본값은 summary로 발견된 누수 수를 출력합니다. 사용 가능한 다른 값은 yesfull로 모두 개별적 누수 세부 정보를 제공하며 no는 메모리 누수 검사를 비활성화합니다.
--undef-value-errors
활성화할 경우 (yes로 설정할 경우) Memcheck는 정의되지 않은 값이 사용되고 있을 때 오류를 보고합니다. 비활성화할 경우 (no로 설정할 경우) 정의되지 않은 값 오류는 보고되지 않습니다. 이는 기본값으로 활성화되어 있습니다. 이를 비활성화하면 Memcheck 속도가 약간 빨라집니다.
--ignore-ranges
적용 가능성을 검사할 때 사용자는 Memcheck가 무시해야 하는 하나 이상의 범위를 지정할 수 있습니다. 여러 범위는 다음과 같이 콤마로 구분합니다. 예: --ignore-ranges=0xPP-0xQQ,0xRR-0xSS
옵션의 전체 목록은 /usr/share/doc/valgrind-version/valgrind_manual.pdf에 있는 문서에서 참조하십시오.

 

 

-----------------------------------------------------------------------------------------------------------------

 

 

5.3.2. Cachegrind로 캐시 사용량 프로파일링

Cachegrind는 시스템의 캐시 계층 및 (옵션으로) 분기 예측과 프로그램의 상호 작용을 시뮬레이션합니다. 이는 시뮬레이션된 첫 번째 레벨의 지시 사항 및 데이터 캐시 사용을 추적하여 이러한 캐시 레벨과 상호 작용한 불충분한 코드를 감지하고 마지막 레벨 캐시 (이것이 두 번째 또는 세 번째 레벨 캐시이던지 간에)에서 메인 메모리로의 액세스를 추적합니다. 결과적으로 Cachegrind와 함께 실행되는 프로그램은 일반적으로 실행되는 것 보다 20-100배 더 느리게 실행됩니다.
Cachegrind를 실행하려면 다음과 같은 명령을 실행합니다. 여기서 program은 Cachegrind로 프로파일링하고자 하는 프로그램으로 대체합니다.
# valgrind --tool=cachegrind program
Cachegrind는 전체 프로그램에서 그리고 프로그램에 있는 각 기능에 대해 다음과 같은 통계를 수집할 수 있습니다:
  • 첫 번째 레벨 지시 캐시 읽기 (또는 실행된 명령) 및 읽기 미스, 마지막 레벨 지시 캐시 읽기 미스;
  • 데이터 캐시 읽기 (또는 메모리 읽기), 읽기 미스, 마지막 레벨 캐시 데이터 읽기 미스;
  • 데이터 캐시 쓰기 (또는 메모리 쓰기), 쓰기 미스 및 마지막 레벨 캐시 쓰기 미스
  • 실행 및 잘못 예측된 조건 분기
  • 실행 및 잘못 예측된 간접 분기
Cachegrind는 이러한 통계에 대한 요약 정보를 콘솔에 인쇄하고 파일에 보다 자세한 프로파일링 정보를 씁니다 (기본값으로 cachegrind.out.pid, 여기서 pid는 Cachegrind를 실행하는 프로그램의 프로세스 ID입니다). 이러한 파일은 다음과 같이 cg_annotate 도구로 추가 처리할 수 있습니다:
# cg_annotate cachegrind.out.pid

참고

cg_annotate는 경로의 길이에 따라 120 자 보다 긴 행을 출력할 수 있습니다. 출력을 명확하게 하고 읽기 쉽게하려면 위의 명령을 실행하기 전 창을 적어도 이 폭으로 확대하는 것이 좋습니다.
또한 Cachegrind에 의해 생성된 프로파일 파일을 비교하여 변경 전 후의 프로그램 성능을 쉽게 도표로 만들 수 있습니다. 이를 위해 cg_diff 명령을 사용합니다. 여기서 first는 초기 프로파일 출력 파일로 second는 후속 프로파일 출력 파일로 바꿉니다:
# cg_diff first second
이 명령은 결합된 출력 파일을 생성하며, 보다 자세한 내용은 cg_annotate를 사용하여 확인할 수 있습니다.
Cachegrind는 출력에 초점을 두는 옵션을 지원합니다. 사용 가능한 옵션 중 일부는 다음과 같습니다:
--I1
콤마로 구분하여 첫 번째 레벨 지시 캐시의 크기, 연결성, 행의 크기를 지정합니다: --I1=size,associativity,line size.
--D1
콤마로 구분하여 첫 번째 레벨 데이터 캐시의 크기, 연결성, 행의 크기를 지정합니다: --D1=size,associativity,line size.
--LL
콤마로 구분하여 마지막 레벨 캐시의 크기, 연결성, 행의 크기를 지정합니다: --LL=size,associativity,line size.
--cache-sim
캐시 액세스 및 미스 카운트의 모음을 활성화 또는 비활성화합니다. 기본값은 yes (활성화)입니다.
이 옵션 및 --branch-sim 모두를 비활성화하면 Cachegrind에는 수집할 정보가 없게 됨에 유의합니다.
--branch-sim
분기 지시 및 예측 실패 수의 모음을 활성화 또는 비활성화합니다. 이는 Cachegrind를 약 25% 느리게 할 수 있으므로 기본값은 no (비활성화)로 설정되어 있습니다.
이 옵션 및 --cache-sim 모두를 비활성화하면 Cachegrind에는 수집할 정보가 없게 됨에 유의합니다.
옵션의 전체 목록은 /usr/share/doc/valgrind-version/valgrind_manual.pdf에 있는 문서에서 참조하십시오.

 

 

-----------------------------------------------------------------------------------------------------------------

 

5.3.3. Massif를 사용하여 힙 및 스택 영역 프로파일링

Massif는 특정 프로그램이 사용하는 힙 영역을 측정합니다. 사용 가능한 공간 및 부기 및 조정 목적으로 할당된 추가 공간 모두에 해당합니다. 이는 프로그램에 의해 사용되는 메모리 양을 줄이는데 도움을 줄 수 있습니다. 이로 인해 프로그램 속도가 개선되고 프로그램을 실행하는 컴퓨터의 스왑 공간을 프로그램이 고갈할 가능성을 감소시킬 수 있습니다. Massif는 프로그램의 어떤 부분이 힙 메모리 할당에 대해 관여하는가에 대한 자세한 정보도 제공합니다. Massif와 함께 실행되는 프로그램은 정상적인 실행 속도보다 약 20 배 더 느리게 실행됩니다.
프로그램의 힙 사용량을 프로파일링하려면 사용하고자 하는 Valgrind 도구로 massif를 지정합니다:
# valgrind --tool=massif program
Massif가 수집한 프로파일링 데이터는 기본값으로 massif.out.pid라는 파일에 기록됩니다. 여기서 pid는 지정된 program의 프로세스 ID입니다.
이러한 프로파일링 데이터는 다음과 같이 ms_print 명령으로 그래프화할 수 있습니다:
# ms_print massif.out.pid
이는 프로그램의 실행에 대한 메모리 사용량을 표시하는 그래프를 생성하며 최고 메모리 할당 지점을 포함하는 프로그램에 있는 다양한 지점에서 할당을 담당하는 사이트에 대한 자세한 정보도 생성합니다.
Massif는 도구의 출력을 지시하는데 사용할 수 있는 명령행 옵션을 제공합니다. 사용 가능한 옵션 중 일부는 다음과 같습니다:
--heap
힙 프로파일링을 수행할 지에 대한 여부를 지정합니다. 기본값은 yes입니다. 이 옵션을 no로 설정하면 힙 프로파일링을 비활성화할 수 있습니다.
--heap-admin
힙 프로파일링을 활성화할 때 관리에 사용할 블록 당 바이트 수를 지정합니다. 기본값은 블록 당 8 바이트입니다.
--stacks
스택 프로파일링을 수행할 지에 대한 여부를 지정합니다. 기본값은 no (비활성화)입니다. 스택 프로파일링을 활성화하려면 이 옵션을 yes로 설정합니다. 하지만 이러한 설정으로 Massif가 현저히 느려지게 될 것임에 유의합니다. 또한 프로파일링된 프로그램이 제어하는 스택 부분의 크기를 보다 알기 쉽게 표시하기 위해 Massif는 메인 스택 크기가 시작 시 0이라고 가정하고 있다는 점에 유의합니다.
--time-unit
프로파일링에 사용되는 시간 단위를 지정합니다. 이 옵션에는 세 개의 유효한 값이 있습니다: 실행된 명령 (i), 기본값으로 대부분의 경우 유용합니다. 실시간 (ms 밀리초 단위), 특정 인스턴스에서 유용합니다. 힙 또는 스택에서 할당/할당해제된 바이트 (B), 이는 다른 시스템에서 가장 재생 가능해서 단기 실행 프로그램 및 테스트 목적으로 유용합니다. 이 옵션은 ms_print로 Massif 출력을 그래프화할 때 유용합니다.
옵션의 전체 목록은 /usr/share/doc/valgrind-version/valgrind_manual.pdf에 있는 문서에서 참조하십시오. 

+ Recent posts