Systems/Unix2010.07.13 11:20
Mac OS X에서 pthread_t 타입은 opaque 타입이다. 간단하게 말하면, int나 uint32_t와 같은 간단한 타입이 아니라, 그 내부 구조에 의존적인 프로그래밍을 하면 안되는 구조체 타입이라는 뜻이다.

보통은 그렇다고 해서 문제가 생길 일은 없는데, 멀티 쓰레드 디버깅을 하려다 보면 문제가 간혹 불거질 때가 있다. 가령 보통의 Unix 플랫폼에서는 다음과 같은 디버깅 매크로를 작성하면 원하는 위치에서 내가 살펴보고자 하는 정보를 화면에 찍어 볼 수가 있다.

#define DUMP(PRNSTR,...)  printf( \
 "dumping   [%08u,%s,%04d] " #PRNSTR "\n", \
 (uint32_t)pthread_self(), __FILE__,__LINE__,__VA_ARGS__)

그러니까 무슨 말인고 하니, 다음과 같이 하면 꼭 printf 하듯이 필요한 정보를 화면에 찍을 수 있다는 소리이다.

DUMP("%d", int_variable);

그러면 화면에 쓰레드 아이디, 파일 이름, 라인 넘버까지 포함된 디버깅 정보가 쭉 찍힌다.

그런데 Mac OS X에서 pthread_self()가 반환하는 pthread_t 값은 opaque타입이기 때문에 uint32_t 타입으로 캐스팅 하려는 시도 자체가 아예 불가능하다. -_-

그래서 다음과 같은 꽁수를 써야 한다. (대체 뭐하는 짓인지...)

#define DUMP(PRNSTR,...)  printf( \
 "dumping   [%08ld,%s,%04d] " #PRNSTR "\n", \
 pthread_self()->__sig, __FILE__,__LINE__,__VA_ARGS__)

WIN32 환경이라면 다음과 같이 해야 할 것이다.

#define DUMP(PRNSTR,...)  printf( \
 "dumping   [%05d,%s,%04d] " #PRNSTR "\n", \
 GetCurrentThreadId(), __FILE__,__LINE__,__VA_ARGS__)

UNIX 소스를 Mac OS X, Win32에까지 신경써서 포팅하려면 실제 코드 말고도 이런 디버깅 매크로에까지, 신경써줘야 할 것들이 무지 많다.

- - -

최근에 이런 짓을 하면서 살다 보니, 인생이 피곤할 뿐 아니라 손가락도 저리다. 잡문 "프로그래머"는 지금 3부 2절까지 완결된 상태이다. 12절까지 작성되면 출판사로 넘겨드릴 생각인데 과연 받아주실 지는 불투명하다는... (내가 봐도 영 구려서.. ㅋㅋ)

신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Languages/Java2010.01.29 19:29
요즘 시스템 퍼포먼스 성능 튜닝을 하고 있습니다. 제가 개발에 참여한 시스템이 Java로 구현되어 있어서, Java 성능 튜닝을 하는 중입니다.

그런데 작업을 하다가 아주 재미난 현상을 발견했습니다. 쓰레드 (아주 작습니다) 를 아주 빠른 주기로 생성해서 프로세싱을 하는데 (하다가 성능이 잘 안나올 것 같아서 쓰레드 풀을 만들어 쓰고 있습니다) 쓰레드 객체가 new되어서 실제로 run 되는데 까지 16ms가 (정확하게는 15.5ms쯤 되는 것 같습니다) 걸리는 현상이 1초당 20~40회 정도 목격된 것이죠.

이 현상이 최초로 목격된 것은 Windows 2003 서버였는데, 비스타나 Windows 7에서도 똑같았습니다.

그래서 쓰레드를 만드는 부분의 코드만 아주 작은 테스트 프로그램으로 분리한 다음에 Windows 시스템들에서 각각 돌려봤습니다. 똑같더군요. ㅋㅋ

같은 프로그램을 Mac OS X에서 돌려봤습니다. 거기서는 그런 현상이 관측되지 않았습니다. Mac OS X에서 실행한 그래프는 다음과 같습니다. Eclipse를 썼습니다. 프로그램 초반에는 쓰레드 풀과 객체 풀이 초기화되느라 약간의 삽질을 하는 것이 보입니다만, sample 수를 감안한다면 적당한 성능을 보입니다.


Windows 플랫폼에서는 가로줄이 0과 16ms 위치에 두 줄 그어집니다. 이 문제를 해결하기 위해서 웹 써치를 좀 했는데, 아무래도 실제로 성능이 그렇게 나오기 때문에 그런 그래프가 그려진다기 보다는, System.currentTimeMillis() 의 resolution이 Windows에서 떨어지기 때문인 것 같더군요.

이 문제를 workaround하기 위한 한 가지 방법은, (measurement가 중요한 환경이라면) System.currentTimeMillis()를 쓰는 대신 System.nanoTime()을 쓰는 것입니다. 그러면 Windows XP 상에서 다음과 같이 성능 측정 결과가 개선되는 것을 볼 수 있습니다.


Y 축은 nanosecond를 millisecond로 변환한 결과입니다. 측정된 성능은 확연하게 나아졌습니다. (Mac OS X보다 낫다고 하긴 뭐합니다. 이 위에 Mac OS X에 대해 그린 그래프는 System.nanoTime을 써서 그린 그래프가 아니라서 정확한 비교자료가 될 수 없거든요.)

신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. Richpapa

    딴 얘기지만, 1. 퍼포먼스 테스트 툴은 무엇으로 하셨나요? 2. 떡밥보다 밑밥에 관심이 가네요. 그래프는 무엇으로 만들었지요?

    2010.01.29 20:50 신고 [ ADDR : EDIT/ DEL : REPLY ]