출처 : http://testors.net/tt/510
타이머 문제로 골몰하다 멀티미디어 라이브러리의 바이너리를 뒤적거리기로 했다. 한참동안 winmm.lib 의 네이티브 코드를 뒤지다가 재미난 것을 한가지 발견. 일단 해당 부분을 뜯어 간단히 인라인 어셈으로 옮겨 보았다.
{
__asm
{
mov edx,dword ptr ds:[7FFE000Ch]
mov eax,dword ptr ds:[7FFE0008h]
}
}
아무런 문서도 없이 바이너리를 뒤지다 얻어낸 정보인지라 저 주소가 무엇을 의미하는지는 나도 모른다. 구글에도 없는것을 보니 완전한 un-documented feature 같다. 어쨌든 저 주소에는 1/10000 초 단위의 시간이 저장되어 있다. 물론 아래와 같이 10000 을 나누어 milli-second 단위로 변환해서 사용하는것도 가능하다.
{
return static_cast< unsigned int >( getMisteryCount()/10000 );
}
mov 를 두번 호출할 뿐인지라 속도는 경이적이다. 빠르지만 최악의 정밀도를 보여주는 GetTickCount() 보다도 4배정도 빠르다. 아무일도 하지 않고 루프만 돈 noproc() 에 거의 근접한다.
getMisteryCount() 와 getElapsedMilliSecond() 의 속도차이의 이유는 64-bit div 연산에 있다. 32-bit 프로세서에서 __int64 나누기를 하려면 수십개의 인스트럭션이 필요하다.
테스트 결과 getMisteryCount() 는 Win95/98/Me 등에선 동작하지 않는다. XP , 2000, 2003 등 NT 커널 기반 OS 에서만 돌아가는 듯 하다. 어쨌건 퍼포먼스 카운트용으로 이보다 더 좋은 타이머는 없을 듯 하다.
>> 타이머 관련 GPG 링크
http://gpgstudy.com/gpgiki/시간%20다루기
'Development > C/C++' 카테고리의 다른 글
ACE 란 무엇인가? (0) | 2011.08.13 |
---|---|
프로젝트에서 Console창을 띄우기 (0) | 2011.08.13 |
코드 실행 시간 측정 방법 정리 (0) | 2011.08.13 |
커널 객체를 이용한 쓰래드 동기화(5) - 뮤텍스 (0) | 2011.08.13 |
커널 객체를 이용한 쓰래드 동기화(4) - 세마포어 (0) | 2011.08.13 |