Doing an Initial Performance Evaluation

OSXDEV

Jump to: navigation, 찾기

Introduction to Performance Overview로 이동


여러분의 코드가 성능상의 문제로 시달리고 있는지 확인하고 싶은가? 어디서 부터 시작해야 할까? 모든 문제가 당장 보이지는 않을 것이다. 여러분은 어떤 작업이 실행하는데 몇초나 걸리는지 알 수 있어도, 너무 많은 CPU 사이클을 소비하는지, 혹은 너무 많은 메모리리가 할당되었는지는 알 수 없다. 바로 이러한 상황에서 애플의 성능분석 툴이 필요하다. 쉽게 지나칠 수 있는 여러분의 프로그램의 다양한 면을 확인하는데 도움을 줄 것이다.

다음의 단락에서 여러분의 프로그램을 분석하기 위해 몇가지 주요한 툴을 사용하는 방법에 대해 간단히 다루고 있다. 이 툴들은 잠재적인 문제를 식별해 내는데 좋고, 성능에 관련된 중요한 자료를 많이 제공해 준다. 그러나 성능 문제에 대해 더 정확한 정보를 제공하는 다른 툴이 있을 수도 있다. 많은 애플의 성능 분석 툴은 메모리 할당 추적이나 누수 탐지 같은 특정한 작업을 위해 설계되었다. 여러가지 다른 툴을 함께 사용하는 것은 특정영역이 문제가 있다는 것을 확신하는데 도움을 준다.


중요: 성능 측정 툴은 성능 문제를 조사하는 것을 도와주기 위해 있다. 분석하는 과정에서 필요한 충분한 데이터가 수집되었는지 확인하라. 실제 문제를 찾아내기 위해 가용한 모든 자료를 신중히 살펴보아야 한다.


목차

[편집] Using top

top은 프로세스에서 잠재적인 문제를 식별해내는데 중요한 도구이다. 이 도구는 주기적으로 샘플된 시스템 사용 수치를 표시해준다. top을 사용하고 그 출력을 이해하는 것은 잠재적인 성능 문제를 식별해 내는데 좋은 방법이다.

top은 CPU 사용과, 메모리 사용(여러가지 카테고리로), 자원 사용(쓰레드나 포트같은), 페이징 이벤트에 대해 주기적으로 갱신한 결과를 출력해준다. 이러한 정보를 이용하여 여러분의 프로그램이 얼마나 많은 메모리를 사용하는지와 몇 퍼센트의 CPU 시간을 소비하는지 알 수 있다. 유휴(idle) 상태의 프로그램은 CPU 시간을 소비하지 않고, 활성화 상태의 프로그램은 작업의 복잡도에 비례하는 CPU 시간을 소비한다.


참고: 시간에 대한 CPU 사용과 그밖의 통계치를 추적하기를 원한다면, BigTop을 쓰길 바란다. BigTop은 시간에 대한 성능의 변화를 그래프로 보여주며 메모리 사용, 페이지 폴트, CPU 사용, 그밖의 데이터를 실시간으로 출력해준다.


목록 4-1은 top 일반적인 출력을 보여준다. 어플리케이션 개발자라면 CPU 사용량, 메모리 상주중인 비공유 메모리 사용량(RPRVT: resident private memory usage), 페이지 인/아웃 비율과 같은 수치에 가장 관심을 기울여야 한다. 이러한 값들은 어플리케이션의 자원 사용량을 여러분에게 알려준다. CPU 사용량이 높다면 어플리케이션이 제대로 조율되지 않았을 가능성이 크다. 메모리 사용량과 페이지 인/아웃 비율의 증가는 어플리케이션의 메모리 사용을 줄여야 할 필요가 있음을 말해준다.


목록 4-1 일반적인 top의 출력

Processes:  36 total, 2 running, 34 sleeping... 81 threads
Load Avg:  0.24, 0.27, 0.23     CPU usage:  12.5% user, 87.5% sys, 0.0% idle
SharedLibs: num =   77, resident = 10.6M code, 1.11M data, 4.75M LinkEdit
MemRegions: num = 1207, resident = 16.4M + 4.94M private, 22.2M shared
PhysMem:  16.0M wired, 25.8M active, 48.9M inactive, 90.7M used, 37.2M free
VM:  476M + 39.8M   6494(6494) pageins, 0(0) pageouts
 
  PID COMMAND      %CPU   TIME      #TH #PRTS #MREGS RPRVT  RSHRD  RSIZE  VSIZE
  318 top           0.0%  0:00.36   1    23    13   172K   232K   380K  1.31M
  316 zsh           0.0%  0:00.08   1    18    12   168K   516K   628K  1.67M
  315 Terminal      0.0%  0:02.25   4   112    50  1.32M  3.55M  4.88M  31.7M
  314 CPU Monito    0.0%  0:02.08   1    63    35   896K  1.34M  2.14M  27.9M
  313 Clock         0.0%  0:01.51   1    57    38  1.02M  2.01M  2.69M  29.0M
  312 Dock          0.0%  0:03.72   2    77    78  2.18M  2.28M  3.64M  30.0M
  311 Finder        0.0%  0:07.68   4    86   171  7.96M  9.15M  15.1M  52.1M
  308 pbs           0.0%  0:01.37   4    76    40   928K   684K  1.77M  15.4M
  285 loginwindow   0.0%  0:07.19   2    70    58  1.64M  1.93M  3.45M  29.6M
  282 cron          0.0%  0:00.00   1    11    14    88K   228K   116K  1.50M
  245 sshd          0.0%  0:02.48   1    10    15   176K   312K   356K  1.41M
  222 SecuritySe    0.0%  0:00.14   2    21    24   476K   828K  1.29M  3.95M
  209 automount     0.0%  0:00.03   2    13    20   336K   748K   324K  4.36M
  200 nfsiod        0.0%  0:00.00   1    10    12     4K   224K    52K  1.22M
  199 nfsiod        0.0%  0:00.00   1    10    12     4K   224K    52K  1.2
[...]

헤더 영역에는 시스템의 전체적인 상태가 출력된다. load 평균치, 전체 프로세스와 쓰레드 갯수, 그리고 개별적인(private), 공유되는(shared), 고정된(wired), 사용가능(free)의 다양한 분류로 나뉘어진 전체 메모리 사용상태와 같은 정보가 나타난다. 그리고 시스템 프레임워크와 관련된 전역적 정보도 포함되어있다. 규칙적인 간격으로 수치가 갱신되어 가장 최근의 시스템 상태를 파악할 수 있다.

표 4-1 은 -w 파라메터를 사용하여 CPU와 메모리 사용 형태를 보여주는 각 컬럼의 데이터에 대해 설명하고 있다. top이 정보를 출력하는 것에 대해 자세한 정보를 알고 싶다면, top(1) 맨 페이지를 보기 바란다.


표 4-1 -w 옵션을 사용한 출력

Column Description
PID BSD 프로세스 ID
COMMAND 어플리케이션 패키지나 실행파일의 이름. (Code Fragment Manager 어플리케이션은 그것을 실행한 네이티브 프로세스의 이름인 LaunchCFMApp를 따른다.)
%CPU 프로세스의 중간에 일정 간격동안 소비된 CPU 사이클의 비율 (커널 공간와 유저 공간 모두 포함).
TIME 이 프로세스가 실행된 후로 소비된 CPU 시간.
#TH 이 프로세스가 소유하고 있는 쓰레드 갯수.
#PRTS (delta) 이 프로세스가 소유하고 있는 Mach 포트 오브젝트 갯수. -w 파라메터가 주어졌을때 활성화 되는 delta 값은 top 이 처음으로 실행되었을때 출력되었던 값에 상대적이다.
#MREG 메모리 구역(region)의 갯수
VPRVT 현재 할당된 비공유(private) 주소 영역 (-w 파라메터 사용시 표시됨)
RPRVT (delta) 메모리 상주중인 비공유 메모리. delta 값은 이 전의 값에 상대적이다.
RSHRD (delta) 메모리 상주중인 공유 메모리. delta 값은 이 전의 값에 상대적이다.
RSIZE (delta) 현재 이 프로세스 연관되어 있는 실제 페이지로써 메모리 상주중인 모든 메모리. 일부는 다른 프로세스에 공유되고 있을 수도 있다. delta 값은 이전의 값에 상대적이다.
VSIZE (delta) 공유메모리를 포함한 현재 할당된 전체 메모리. delta 값은 top이 처음으로 실행되었을때 출력된 값에 상대적이다.

이 값은 대부분의 Mac OS X 프로세스와 관련이 없다. 모든 어플리케이션은 프레임워크와 라이브러리 코드를 포함하기 위한 공유 영역을 위해 가상의 큰 크기(역자 주: 크기만 크고 실제로 할당되진 않았음)를 갖고 있다.

RPRVT 데이터 (상주중인 비공유 페이지) 는 어플리케이션이 사용하고 있는 실제 메모리양이 얼마나 되는지 측정하는데 좋은 척도가 된다. RSHRD 컬럼 (상주중인 공유 페이지) 은 공유 맵핑(mapped) 파일 이나 다른 작업과 공유되는 메모리 오브젝트의 메모리 상주중인 페이지를 보여준다.


참고: top 툴은 테스크에 맵핑된 공유 라이브러리 별도의 페이지 갯수를 제공해 주지 않는다. top 툴은 윈도우 버퍼가 윈도우 서버와 공유되기 때문에 "shared memory" 카테고리에 윈도우의 메모리 사용량을 나타내준다.


표 4-2는 -e, -d, -a 옵션으로 활성화 되는 event-counting 모드의 출력에서의 각 컬럼값을 보여주고 있다.


표 4-2 -d 옵션을 사용한 출력 결과

Column Description
PID BSD 프로세스 ID
COMMAND 어플리케이션 패키지나 실행파일의 이름. (Code Fragment Manager 어플리케이션은 그것을 실행한 네이티브 프로세스의 이름인 LaunchCFMApp를 따른다.)
%CPU 프로세스의 중간에 일정 간격동안 소비된 CPU 사이클의 비율 (커널 공간와 유저 공간 모두 포함).
TIME 이 프로세스가 실행된 후로 소비된 CPU 시간.
FAULTS 페이지 폴트 갯수
PAGEINS 페이징을 위해 pager로 부터 요청된 페이지 인 갯수.
COW_FAULTS 페이지가 복사될때 발생된 폴트 갯수 (일반적으로 copy-on-write 폴트에 의해 발생됨)
MSGS_SENT 프로세스에 의해 보내진 Mach 메세지 갯수
MSGS_RCVD 프로세스에 의해 받은 Mach 메세지 갯수
BSDSYSCALL 프로세스에 의해 발생된 BSD 시스템 콜 갯수
MACHSYSCALL 프로세스에 의해 발생된 Mach 시스템 콜 갯수
CSWITCH 프로세스로 컨텍스트 스위칭(context switching)한 횟수 (커널 스케쥴러에 의해 실행할 시간을 할당받은 횟수)


[편집] Quartz Debug 사용하기

Quartz Debug는 드로잉 코드의 효율성을 결정하는 중요한 도구이다. 이 도구는 드로잉 호출로부터 정보를 모아서 프로그램의 어디가 드로잉을 수행하는지 그리고 이것이 불필요한 중복 드로잉인지를 알아낸다. 그림 4-1은 Quartz Debug의 옵션 윈도우를 보여준다.


그림 4-1 Quartz Debug 옵션
그림:a_performance_overview_Quartz_debug.gif

주 모드에서, Quartz Debug는 코드의 어디가 드로잉을 하는지 시각적으로 보여준다. 이것은 화면이 다시 그려질 영역에 노란 상자를 그려주고 그 내용이 그려지기 전에 잠깐동안 멈춘다. 노란색이 깜빡거리는 패턴을 통해 필요이상으로 드로잉이 수행되는 지점을 찾아낼 수 있다. 예를 들면, 커스텀 뷰의 작은 영역만 갱신되면 충분한 상황에서, 전체 화면을 다시 그리고 싶지는 않을 것이다. 시스템 컨트롤이 연속으로 몇번을 다시 그려지는 것이 발견되면, 이것은 그 컨트롤의 속성을 변경하기 전에 감출 필요가 있다는 것을 가리킨다.

이 툴은 정확히 똑같은 내용이 다시 그려지는 스크린 영역을 식별해 내는 기능도 갖고 있다. "Flash identical updates" 옵션을 선택하면, 결과 비트값이 현재 내용과 동일한 영역에 빨간색을 표시해준다.


[편집] Using Spin Control

만약 어플리케이션 어떤 순간에 응답하지 않는다면, 윈도우 서버는 커서를 빙글 빙글 도는 무지개색 바퀴 모양으로 바꾸어서 이러한 상황을 알린다. 만약 여러분의 어플리케이션이 응답하지 않게 된다면, 그 시간동안 샘플링을 하면 이유를 밝혀내는데 도움이 될 것이다. 그러나 여러분이 Shark 나 다른 툴을 사용할 수 있다 하더라도, 응답하지 않는 기간동안 샘플링 정보를 얻기 위해 충분히 빨리 그것들을 실행하기가 어려울 것이다. 이런 경우 Spin Control은 좋은 해결책이 될 것이다.

Spin Control은 응답하지 않는 어플리케이션을 자동으로 모니터링 하는 도구이다. 테스트 하고자 하는 어플리케이션이 동작될 컴퓨터에 Spin Control을 실행시켜 놓는다. 빙글빙글 도는 커서가 나타나면, Spin Control은 추적 정보를 가져와서 그림 4-2 처럼 메인 윈도우에 보여준다.


그림 4-2 Spin Control의 메인 윈도우
그림:A_performance_overview_Sc_sample_window.gif‎

특정 세션의 추적 정보를 보고 싶으면, 해당 세션을 선택하고 Open을 클릭한다, 샘플링 데이터를 담고 있는 브라우져 윈도우 (그림 4-3)가 나타난다. 이 데이터를 이용하여 어플리케이션이 응답하지 않을때 실행되고 있는 코드를 확인할 수 있다. 왼쪽 아래에 있는 컨트롤들은 샘플이 출력되는 방식을 변경해 준다. 오른쪽 아래의 버튼들은 호출 스택들을 정리하여 가장 관련있는 호출 스택에 집중할 수 있게 해준다.


그림 4-3 Spin Control의 sample 윈도우
그림:A_performance_overview_Spin_control_main.gif

호출 스택의 전체 목록을 보고 싶으면, 메인 윈도우의 "Show text report" 버튼을 클릭한다. 이 형식은 다른 문서에 복사해서 붙여넣기 가능한 형식화된 버전의 전체 데이타 집합을 보여준다.


[편집] Using Shark

Shark는 코드에서 성능상의 문제점을 찾아내는데 사용할 수 있는 가장 강력한 분석 툴 중에 하나이다. Shark는 시간에 기반한 프로그램 실행 프로파일, 함수 호출 추적, 시간에 따른 메모리 할당 그래프를 생성해 낸다. Shark를 통해 여러분의 프로그램이나 전체 시스템 정보를 추적할 수 있다. 심지어 드라이버나 커널 확장(extension)같은 커널 엔티티의 실행 정보를 잡아내기도 한다.

역자 주: Shark를 설치하기 위해서 ADC의 Tools Download에서 CHUD Tools을 다운받아 설치하면 된다.

Shark의 이러한 강력한 성능에도 불구하고, 툴의 사용법이 매우 쉽다. Shark를 실행하면 그림4-4와 같은 윈도우가 나타난다. Start 버튼을 누르면 (또는 Option-Escape 단축키를 사용해도 된다) 전체 시스템 프로세스에 대해 샘플링을 시작한다. 버튼을 다시한번 누르면 자료를 모으는 것을 중지하고, 샘플결과를 출력해 준다 (그림 4-5).


그림 4-4 Shark 실행 윈도우
그림:A_performance_overview_Shark_main.gif‎

샘플링을 하나의 프로세스에 대하여 처리하도록 제한하고 싶다면, 오른쪽의 팝업메뉴에서 프로세스를 선택할 수 있다. 또한, "Time Profile" 이외의 다른 작업을 수행하고 싶으면 Start를 클릭하기 전에 설정 팝업메뉴에서 적절한 옵션을 선택한다.

샘플링을 중단하면, Shark는 그림 4-5와 같이 프로파일 윈도우에 모은 데이터를 출력해준다. 이것이 여러분이 잠재적인 문제들을 확인하는데 사용할 메인 윈도우이다. 윈도우의 출력을 heavy, tree, heavy and tree 뷰로 설정할 수 있다.


그림 4-5 Shark profile 윈도우
그림:A_performance_overview_Shark_samples.gif

heavy 뷰는 함수가 얼마나 자주 호출되었는지를 기준으로 정렬되어있다. 이 뷰는 여러분의 프로그램에서 hot spot(역자 주: 자주 실행되어 성능을 위해 튜닝이 필요한 지점)을 식별하기 쉽게 해준다. 이 뷰에서 최상위 쪽에 놓인 함수들은, 한번 확인해 볼 필요가 있다. 함수가 제대로 최적화 되지 않았다면 높은 가중치를 갖는 경향이 있지만, 일반적으로 다른 곳에서 빈번히 호출되는 경우에 높아진다. 이러한 사실은 이러한 함수를 호출하는 상위 레벨의 알고리즘이 효율적이지 못하다는 것을 가리킨다.

tree 뷰는 같은 데이터를 호출 구조에 따라 조직화하여 보여준다. 이 뷰는 특정한 함수가 어떤 맥락으로 호출되었는지 쉽게 알수있게 해준다. 이것은 호출 스택 데이터를 보는 더 전통적인 방법이고, heavy view와 결합되어 hot spot을 추적하고 주위 맥락을 빠르게 살펴볼 수 있다.

Shark profile 윈도우는 "Data Mining" 기능을 통해서 부적절한 코드나 라이브러리를 쉽게 걸려낼 수 있게 해준다. Data Mining 메뉴는 심볼과 라이브러리를 축출하거나 평탄화시키는 몇몇 옵션을 포함하고 있다. 이런 명령을 적용시키면, Shark는 이러한 심볼과 라이브러리를 실행하는데 드는 비용을 호출한 함수에 옮긴다. 예를 들면, 여러분의 코드가 Core Foundation의 몇몇 함수를 호출하는 걸 알고, Core Foundation 라이브러리를 축출시키면, Core Foundation에서 소비되는 시간은 여러분의 코드가 소비한 시간에 나타나게 된다. 만약 코드가 소비한 시간이 눈에띄게 증가하면, Core Foundation 함수의 사용을 줄일 방법을 모색해봐야 할 것이다.

Shark는 code 뷰를 통해 주어진 함수의 성능 문제를 확인할 수 있게 해준다. 함수를 더블클릭하면 가능한 경우 그 함수의 소스 코드를 화면에 출력해 준다(그림 4-6). 코드의 각 줄에 색깔이 칠해져 수행되는 시간이 반영된다. 노란색이 밝을수록 프로파일 하는 동안 코드를 실행하는데 더 많은 시간이 소요되었다는 것을 뜻한다.


그림 4-6 Shark code 화면
그림:A_performance_overview_Shark_code_listing.gif‎

Shark는 구체적인 튜닝 팁과 설명을 여백에 나타내기도 한다. 느낌표 모양의 아이콘을 클릭하면 코드의 성능을 향상시킬 팁을 화면에 표시해준다. comment 컬럼은 요악된 팁을 표시해준다.

Shark와 그 기능에 대해 더 많은 정보가 필요하면, Help > Shark Help를 선택하여 Shark User Guide를 보기 바란다.