DirectX

[DirectX]고해상도 타이머

FORHAPPy 2022. 1. 6. 12:38

타이머를 사용하는 이유 : 컴퓨터 성능에 따라 일정 시간당 호출되는 Update() 의 빈도가 다르기 때문

 


해상도란?

 

얼마나 많은프레임을 쪼개서 표현할 수 있는가

GetTickCount는 1/1000까지 표현이 가능하다. 

QeuryPerformanceTimer의 경우에는 하드웨어마다 주파수가 다르므로 

하드웨어마다 해상도도 다르다.

 


GetTickCount()

 

Kernael.dll 에 존재하며 시스템(운영체제)가 시작된 이후로부터 카운트 된다.  단위는 millisecond 단위로 나타낸다. 

시간은 DWOD형으로 저장된다. 49.7일만 표현이 가능하다. 넘어가면 0으로 초기화 된다. 

 


 

QeuryPerformanceTimer

 

 

1.  LARGE_INTEGER 구조체를 사용

 

64비트 정수형을 담는다. 

컴파일러가 64비트를 지원할땐 64비트 정수형 변수에 32비트 지원시에는 32비트 정수형 변수에 64비트 측정값을 나워서 저장한다.

 

값은 64비트 부호있는 정수형인 QuardPart에 저장된다. 

멤버변수로 LONGLONG 자료형의 QuardPart가 있다. 

 

 

2.   BOOL QueryPerformanceFrequency (LARGE_INTEGER *lpFrequency);

 

64비트의 정수포인터를 넘겨주면 주파수를 이 변수에 대입해준다. 

1초에 이 함수가 리턴하는 만큼 카운트가 증가한다. 

주파수는 시스템 속도에 따라 다르며 어떤 시스템에서는 CPU의 클럭수가 주파수로 사용되기도 한다. 

주파수는 부팅후에는 절대 변하지 않는다. 

리턴값이 0일 경우 이 타이머를 지원하지 않는다. 이때는 이 함수를 사용할 수 없다. 

 

3.  BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)

 

특정시간의 카운트를 조사할 때 사용한다. 

64비트로 카운트를 조사하므로 최대 1844경 까지 카운팅 할 수 있다. 

주파수가 120만 이라고 했을떄 하루 3784조가 되며 64비트 정수로 최대 4873년 동안 카운팅을 할 수 가 있다. 

함수가 호출된 시점의 타이머 값이고, 이 값은 진동수가 계속 누적으로 카운팅된다.

 

 

4. 주의할 점

 

멀티코어 / 멀티프로세서 에서는 코어간의 사이클 카운터가 동기화 되지 않는다. 

그러므로 하나의 스레드에서 수행하고 해당 스레드를 하나의 프로세서에 고정시켜야 한다.


CTimeMgr

  1. 싱글톤으로 만들어 주었다.   Get_TimeDelta() 함수를 전역에서 접근하여 델타 타임을 얻어오기 위함.
  2. m_fTimeDelta = float(m_CurrentTime.QuadPart - m_OldTime.QuadPart) / m_CpuTick.QuadPart;
    m_OldTime = m_CurrentTime;
  3. 구해준 m_fTimeDelta 을 리턴