기타 2008. 3. 26. 15:03
유튜브에서 본 Xcode 3로 계산기를 만드는 동영상입니다. (요즘 이렇게 눈요기만으로 레퍼드로 업그레이드를 참고 있습니다) 아직 완성된 것은 아니고 2부까지만 나온 것 같습니다.

보면서 두가지 생각이 들었습니다. 첫번째는 'Xcode 3을 써보고 싶다' 입니다. 두번째는 multiply, divide 타이핑을 하는데 오늘 오전에 본 댓글 때문에 뜨끔하더군요. ^^;

* Building a Cocoa Calculator Application with XCode 3 for Mac


* Building a Cocoa Calculator App Using XCode 3 (Part 2)
AND

오늘 오랫만에 digg에 들렀다가 Google Code University - Free Training from Google란 내용을 보았습니다. 댓글중에 "It's a google world, we're just livin' in it"란 말이 재미있네요. 하지만 우리나라에서는 아니겠죠.

사용자 삽입 이미지
Googl Code University로 가보니 좌측과 같이 튜토리얼, 동영상 강좌와 강연을 무료로 제공하는 온라인 강좌를 하고 있습니다. 아래와 같은 주제들이 있었습니다.

* AJAX Programming
* Distributed Systems
* Web Security
* Languages


언어 코스에는 C++, Java, Python이 있습니다. 저 세언어가 가장 많이 쓰이는 언어라서 선택된 것인지 구글에서 많이 쓰기 때문인지는 잘 모르겠습니다. 아무튼 인기있는 언어이기 때문이겠죠.

프로그래밍에 유용한 툴들을 소개하는 Tools 101 메뉴에는 현재 Introduction to Databases and MySQLSoftware Configuration Management의 2개의 자료가 있습니다.

앞으로도 다양한 자료들이 많이 올라 왔으면 좋겠습니다. 프로그래밍 공부도 하고 영어 공부도 하고 일석이조네요. ^^
AND

사용자 삽입 이미지
샤크는 프로그램의 성능 측정 도구(프로파일러)입니다. 성능 튜닝은 사냥꾼의 동물적인 감각이 필요하고 상어가 먹이를 추적하는데 가장 앞선 동물이라 샤크라는 이름을 지었다고 합니다.

벌레들을 잡아 먹는 사마귀(mantis)로 이름을 지은 버그 추적 시스템처럼 상어(shark)도 재미있는 이름 같습니다.



0. 준비
실행은 /Developer/Applications/Performans Tools/Shark를 클릭하거나, Xcode의 Debug 메뉴에서 Lauch Using Performans Tool에서 Shark를 클릭하여 실행 합니다.

만약 해당 디렉토리에 Shark가 없다면 Xcode 설치시 CHUD Tools를 선택하지 않았기 때문입니다. Xcode 설치 파일을 이용해서 Shark를 설치하면 됩니다.

1. 테스트 코드 작성

테스트를 위해서 Xcode에서 아래와 같은 샘플코드를 작성합니다.

#import <Foundation/Foundation.h>

@interface Musik1 : NSObject {
}
@end
@implementation Musik1
-(void) run {
    int i, n;
    for (i = 0; i < 100; i++) {
        n = i * i;   
    }
}
@end

@interface Musik2 : NSObject {
}
@end
@implementation Musik2

 - (void) run {
    int i, n;
    for (i = 0; i < 1000; i++) {
        n = i * i;   
    }
}
@end

void Run()
{
    int i;
       
    for(i = 0; i < 10000; i++) {
        Musik1 *musik1 = [[Musik1 alloc] init];
        Musik2 *musik2 = [[Musik2 alloc] init];
       
        [musik1 run];
        [musik2 run];
   
        [musik1 release];
        [musik2 release];
    }
}

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // insert code here...
    Run();
   
    [pool release];
   
    return 0;
}

무식하게 돌아가는 코드를 작성해 보자 하고 생각없이 이름을 지었는데, 그냥 변경없이 포스팅에 사용하기로 했습니다. 나중에 다른 툴에서도 예제로 사용하기 위해 클래스를 두개 만들고 메모리를 할당하고 해제하는 코드를 넣었습니다.

소스는 10000번 돌면서 Musik1과 Musik2를 생성 해제 하면서 각각의 run 메소드가 실행됩니다. Musik1의 run 메소드는 다시 100번 돌고 Musik2는 더 무식해서 1000번 돌도록 하였습니다.

2. Shark 실행
이제 빌드를 하고 Xcode의 Debug 메뉴에서 Lauch Using Performans Tool/Shark를 클릭합니다. 아래와 같이 Shark가 실행된 모습을 보실 수 있습니다.

사용자 삽입 이미지

샤크에서 좌측의 Start 버튼을 클릭합니다. 아래와 같은 창이 뜨면 원하시는 옵션을 선택한 후 [OK]를 클릭합니다.

사용자 삽입 이미지

이제 프로그램이 런칭되어 분석을 시작합니다. 30초 내에 프로그램이 종료하지 않으면 자동으로 종료하고 분석된 결과를 보여줍니다. Config 메뉴에서 View Mini Config Editor를 선택하시면 실행 전에 제한시간과 다른 샘플링 옵션을 변경하실 수 있습니다.

사용자 삽입 이미지
재밌는 것은 분석중에는 아이콘에서 상어의 모습이 붉은 색으로 변합니다. 맹렬히 먹이감을 쫓고 있는 것 같습니다. 무섭습니다.


3. 샘플링 데이터 확인
1) 프로파일 브라우져
완료되면 아래와 같이 분석된 결과를 보여 줍니다. 우측 하단의 View 항목에서 표현 방식을 변경할 수 있습니다. Heavy는 항목별로 Tree는 말 그대로 트리 구조로 결과를 보여 줍니다. 아래의 이미지를 보시면 둘의 차이점을 확인하실 수 있습니다. 각 컬럼은 아래와 같습니다.

  • self - 행당 항목의 비율
  • Total - 하위 항목을 모두 포함한 전체 비율
  • Library - Symbol이 포함된 라이브러리
  • Symbol  - 심볼 (함수명)

사용자 삽입 이미지

위를 보시면 실행시간의 64.1%를 차지하는 [Musik2 run]을 중점적으로 점검해야 됨을 알 수 있습니다. [Musik2 run] 항목을 더블클릭하면 아래와 같이 해당 소스가 오픈됩니다. 우측 상단의 버튼들을 클릭하면 원본 소스, 어셈블리 또는 같이 볼수 있습니다.
 
2) 소스코드 브라우져
사용자 삽입 이미지

코드에서 직접 부하를 확인할 수 있습니다. [i] 아이콘이 있는 곳은 해당 코드에 대한 도움말이 있습니다. 아이콘을 클릭하면 전체 내용을 볼 수 있습니다. 아래는 Both 버튼을 클릭하여 원본 소스와 어셈블리를 같이 보여 주는 모습니다.

사용자 삽입 이미지

run 함수에서 'n=i * i(진한 갈색 부분)'에서 실행속도의 64.2%를 소비하고, 나머지 for 루프를 위한 'i++, i < 1000(연한 갈색)'에서 나머지를 소비하고 있는 것을 알 수 있습니다.

좌측의 'n = i * i' 에 해당되는PPC 어셈블리 코드를 간단히 살펴 보겠습니다. (우측 하단의 [Asm Help]를 클릭하시면 어셈블리 명령어 셋에 관한 간단한 설명을 보실 수 있습니다)

lwz r2, 28(r30) // 28(r30)의 메모리 값(i)을 r2 레지스터로 불러 옵니다.
lwz r0, 28(r30) // 28(r30)의 메모리 값(i)을 r0 레지스터로 불러 옵니다.
mullw r0,r2,r0 // r2, r0을 곱한 값을 다시 r0에 저장합니다.
stw r0, 24(r30) // 레지스터 r0의 값을 28(r30)의 메모리(n)에 저장합니다.

위는 제 PPC의 어셈블리 모습이며 인텔맥에서는 아래와 같습니다.
 
L3:
    .stabd    68,0,8
    movl    -16(%ebp), %eax
    imull    -16(%ebp), %eax
    movl    %eax, -12(%ebp)
    .stabd    68,0,7
    leal    -16(%ebp), %eax
    addl    $1, (%eax)
L2:
    cmpl    $99, -16(%ebp)

4) Chart 뷰
이제 Chart를 클릭하여 함수의 호출 경로가 기록되어 있는 call stack을 확인해 보겠습니다. Chart에서는 1ms마다 call stack을 기록한 내용을 그래프와 목록으로 확인할 수 있습니다. 그래프 또는 목록을 클릭하면 좌측에서 해당 시간의 call stack의 내용을 확인할 수 있습니다.
사용자 삽입 이미지

"우선 여기서 알수 있는 것은 제 맥이 엄청 느리다는 것입니다. 대부분의 맥에선 아래의 샘플링 시간이 보시는 것 보다 적게 나올 것입니다. 혹시 사용하는 맥이 너무 빨라 Shark가 붉게 변하는 모습을 못 보셨으면 반복 횟수를 늘리거나 다른 코드를 넣어 무식이의 run을 더 무식하게 만드시면 됩니다."

초기에 스택이 큰 것은 기동 시 초기화 루틴에서 부르는 것들입니다. 전체적으로 5로 나타나는 것은 대부분의 로드가 [Musik1(또는 2) run]일어 나기 때문에 위이미지의 좌측에서 보시는 것 처럼 start > _start > main > Run > [Musik1(또는 2) run]의 5단계이기 때문입니다.

우측 하단 View에서 CPU를 선택할 수 있는데 저는 PPC라 1개가 나오지만 인텔 코어듀오가 장착된 맥에선 2개의 CPU가 나올 것입니다.

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

Shark에서는 샘플링된 데이터를 파일로 저장할 수 있습니다. 현재 데이터를 저장하고 최적화를 수행하고 다시 Shark를 실행하여 이전 데이터와 비교해보며 최적화의 결과를 확인할 수 있습니다.

Shark에 대한 자세한 내용은 ADCShark User Guide 를 참조하시고, Shark 이외에 /Developer/Applications/Performans Tools/ 디렉토리에서 유용한 다른 툴들도 확인하실 수 있습니다.

'Xcode 2 > Tip' 카테고리의 다른 글

주석내의 __MyCompanyName__ 변경  (2) 2008.03.04
다이알로그 윈도우 구현  (2) 2008.01.09
Xcode에서 디버깅 작업  (6) 2007.12.20
Xcode에서 Flex 개발하기  (2) 2007.12.08
Xcode에서 파이어폭스 플러그인 컴파일 하기  (0) 2007.12.04
AND