ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ์ธก์ ํ๋ ๋ฐฉ๋ฒ. ํ๋ก๊ทธ๋จ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฑ๋ฅ์ ์์๋ณด๋ ๋ฐฉ๋ฒ์ค ํ๋๊ฐ ์ํ์๊ฐ ์ธก์ ์
๋๋ค.
HighResolutionTimer ์ฌ์ฉํ๊ธฐ ¶
Windows ์์์ ์ํ์๊ฐ์ธก์ ๋ฐฉ๋ฒ.
~cpp BOOL QueryPerformanceFrequency(LARGE_INTEGER* param) BOOL QueryPerformanceCounter(LARGE_INTEGER* param)์๊ธฐ ๋ Windows APIํจ์๋ฅผ ์ฌ์ฉํด์ ์ํ ์๊ฐ์ ์ธก์ ํ ์ ์์ต๋๋ค.
์์ ¶
์ํ์๊ฐ ์ธก์ ์ฉ C++ Class. ์ํ์๊ฐ ๋จ์๋ Sec ์
๋๋ค. ๋จ HighResolutionTimer๋ฅผ ์ง์ํ๋ ํ๋ก์ธ์๊ฐ ํ์ํฉ๋๋ค.
๋ค์์ Binary Search ์ ํผํฌ๋จผ์ค ์ธก์ ๊ด๋ จ ์์ . CTimeEstimate ํด๋์ค๋ฅผ ๋ง๋ค์ด ์๋๋ค.
๋ค์์ Binary Search ์ ํผํฌ๋จผ์ค ์ธก์ ๊ด๋ จ ์์ . CTimeEstimate ํด๋์ค๋ฅผ ๋ง๋ค์ด ์๋๋ค.
~cpp #include <windows.h> #include <time.h> #include <stdio.h> class CTimeEstimate { protected: __int64 m_nStart, m_nEnd, m_nFreq; public: CTimeEstimate () { m_nStart = m_nEnd = m_nFreq = 0; QueryPerformanceFrequency((LARGE_INTEGER*)&m_nFreq); } ~CTimeEstimate () { } void Start () { QueryPerformanceCounter((LARGE_INTEGER*)&m_nStart); } void End () { QueryPerformanceCounter((LARGE_INTEGER*)&m_nEnd); } double Result () { return (double)(m_nEnd - m_nStart)/m_nFreq; } }; void Init (int S[]); int getRandNum (int nBoundary); int BinarySearch (int nBoundary, int S[], int nKey); int main (void) { CTimeEstimate est; int S[30001]; int i, nRandNum, nLocation; int nBoundary = 2000; Init (S); nRandNum = getRandNum (nBoundary); est.Start (); for (i=0;i<1000;i++) { nLocation = BinarySearch (nBoundary, S, nRandNum); } est.End (); // result printf ("random number : %d \n", nRandNum); printf ("location : %d\n", nLocation); printf ("estimated time : %f \n", est.Result ()); return 0; } void Init (int S[]) { for (int i=1;i<30001;i++) { S[i] = i; } } int getRandNum (int nBoundary) { time_t t; t = time (NULL); srand (t); return rand () % nBoundary; } int BinarySearch (int nBoundary, int S[], int nKey) { int nBoundaryLow, nBoundaryHigh, nMiddleKey; nBoundaryLow = 1; nBoundaryHigh = nBoundary; while ((nBoundaryLow <= nBoundaryHigh) && nMiddleKey) { nMiddleKey = (nBoundaryLow + nBoundaryHigh) / 2; if (nKey == S[nMiddleKey]) return nMiddleKey; else if (nKey < S[nMiddleKey]) nBoundaryHigh = nMiddleKey - 1; else nBoundaryLow = nMiddleKey + 1; } return FALSE; }
ftimeํจ์, timeb ๊ตฌ์กฐ์ฒด์ ์ฌ์ฉ ¶
๋น๊ต์ CPU์ OS์ ์์กด์ ์ด์ง ์์ ๋ฐฉ๋ฒ์ผ๋ก๋ ftime ํจ์์ timeb ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋ฐ๋ฆฌ์ธ์ปจ๋ ๋จ์๊น์ง ๋ฐ์ ์ ๊ณต๋์ง ์์ต๋๋ค. sys/timeb.h ํค๋์ ์ ์๋ ๋ด์ฉ์ด ANSI C ๋ ์๋๋ผ๊ณ ์๊ณ ์์ต๋๋ค.
ftime ํจ์์ ํ๋กํ ํ์ ¶
~cpp void ftime(struct timeb* buf)
timeb ๊ตฌ์กฐ์ฒด ¶
~cpp struct timeb { long time ; /* seconds since 00:00:00, 1/1/70, GMT */ short millitm ; /* fraction of second (in milliseconds) */ short timezone ; /* difference between local time and GMT */ short dstflag ; /* 0 if daylight savings time is not in effect */ };
ftime ํจ์์ timeb ๊ตฌ์กฐ์ฒด ์ฌ์ฉ ์ ¶
~cpp #include <sys/timeb.h> #include <stdio.h> void show_est(struct timeb start, struct timeb end); int main(void) { struct timeb start, end; ftime(&start); sleep(1); ftime(&end); show_est(start,end); } void show_est(struct timeb start, struct timeb end) { int time, millitm; time = (int)(end.time - start.time); millitm = (int)(end.millitm - start.millitm); if (millitm<0) { time --; millitm += 1000; } printf (" %d ms ๊ฑธ๋ ธ์ต๋๋ค.\n",time*1000+millitm); }
RDTSC ์ ์ฌ์ฉ ¶
๋ง์ดํฌ๋ก ์ํํธ์จ์ด 1999๋
2์ํธ ํ
ํฌ๋์ปฌ ์ปฌ๋ผ์ ๋์จ ๋ฐฉ๋ฒ์
๋๋ค.
ํํฐ์ ์ด์์ CPU์์ RDTSC(Read from Time Stamp Counter)๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ํํฐ์์ ๋ด๋ถ์ ์ผ๋ก TSC(Time Stamp Counter)๋ผ๋ 64๋นํธ ์นด์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ ์ด ์นด์ดํฐ์ ๊ฐ์ ํด๋ญ ์ฌ์ดํด๋ง๋ค ์ฆ๊ฐํ๋ค. RDTSC๋ ๋ด๋ถ TSC์นด์ดํฐ์ ๊ฐ์ EDX์ EAX ๋ ์ง์คํฐ์ ๋ณต์ฌํ๋ ๋ช ๋ น์ด๋ค. ์ด ๋ช ๋ น์ 6์์ 11ํด๋ญ์ ์์ํ๋ค. Win32 API์ QueryPerformanceCounter๋ ์ด ๋ช ๋ น์ ์ด์ฉํด ๊ตฌํํ ๊ฒ์ผ๋ก ์ถ์ธก๋๋ค. ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
ํํฐ์ ์ด์์ CPU์์ RDTSC(Read from Time Stamp Counter)๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ํํฐ์์ ๋ด๋ถ์ ์ผ๋ก TSC(Time Stamp Counter)๋ผ๋ 64๋นํธ ์นด์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ ์ด ์นด์ดํฐ์ ๊ฐ์ ํด๋ญ ์ฌ์ดํด๋ง๋ค ์ฆ๊ฐํ๋ค. RDTSC๋ ๋ด๋ถ TSC์นด์ดํฐ์ ๊ฐ์ EDX์ EAX ๋ ์ง์คํฐ์ ๋ณต์ฌํ๋ ๋ช ๋ น์ด๋ค. ์ด ๋ช ๋ น์ 6์์ 11ํด๋ญ์ ์์ํ๋ค. Win32 API์ QueryPerformanceCounter๋ ์ด ๋ช ๋ น์ ์ด์ฉํด ๊ตฌํํ ๊ฒ์ผ๋ก ์ถ์ธก๋๋ค. ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
~cpp #define rdtsc(x) \ { __asm __emit 0fh __asm __emit 031h __asm mov x, eax} #define rdtscEx(low, high) \ { __asm __emit 0fh __asm __emit 031h __asm mov low, eax __asm mov high, edx}๊ฐ๋จํ๊ฒ 32๋นํธ ์ ์๋ก ์ฌ์ฉํ๊ณ ์ ํ๋ค๋ฉด RDTSC๋ช ๋ น์ด ์นด์ดํฐ์์ ๊ฐ์ ธ์ค๋ ๊ฐ ์ค์์ EAX์ ๋ด๊ธด ๊ฐ๋ง์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ด ์๋ค. ์งง์ ์๊ฐ๋์ ์ธก์ ํ๋ค๋ฉด EAX์ ๋ด๊ธด ๊ฐ๋ง ๊ฐ์ง๊ณ ๋ ํด๋ญ์ ์ธก์ ํ ์ ์๋ค. 64๋นํธ๋ฅผ ๋ชจ๋ ์ด์ฉํ ๋ ค๋ฉด LARGE_INTEGER ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์ฉํ๋ค.
~cpp LARGE_INTEGER start, end rdtscEx(start.LowPart, start.EndPart); ..... // ์ธก์ ๊ตฌ๊ฐ rdtscEx(end.LowPart, start.EndPart); elasped_time = *(__int64*)&end - *(__int64*)&start;rdtscEx๋ช ๋ น์ 36ํด๋ญ์ ์์ํ๋ฉฐ ์ธก์ ๊ตฌ๊ฐ์ ํด๋ญ ๋จ์๋ก ์ธก์ ํ ์ ์๋ ๊ฐ๋ ฅํ ์๊ฐ ์ธก์ ๋ฐฉ๋ฒ์ด๋ค. ํ์ง๋ง ์ด ๋ฐฉ๋ฒ์ ํด๋ญ ์๋ง ์ธก์ ํ ๋ฟ ์๊ฐ์ ์ ์๋ ์๋ค. ์ ํํ ์๊ฐ์ ์๋ ค๋ฉด ์์คํ ์ CPUํด๋ญ์ ์์์ผ ํ๋ฉฐ ์ธก์ ํ ํด๋ญ๊ฐ์ CPUํด๋ญ์ผ๋ก ๋๋์ด์ผ ์๊ฐ์ด ๋์จ๋ค. RDTSC๋ช ๋ น์ ์ํํ ๋ CPU๊ฐ ์ํ ์๋ ํฅ์์ ์ํด์ CPU ๋ช ๋ น ์์๊ฐ ๋ฐ๋ ์ ์๊ธฐ ๋๋ฌธ์ CPUID๋ช ๋ น์ ์ ์ ์ํํด ๋ช ๋ น ์์๋ฅผ ๋ง์ถฐ์ผ ํ๋ ๊ฒฝ์ฐ๋ ์๋ค. ์์ธํ ์ค๋ช ์ ์ธํ ์์ ์ ๊ณตํ๋ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ ์ํ RDTSC ๋ช ๋ น ์ฌ์ฉ๋ฒ์ ์ฐธ์กฐํ๊ธฐ ๋ฐ๋๋ค.
Windows๋ Multi-Thread๋ก ๋์ํ์ง ์์ต๋๊น? ์ ์ฝ๋๋ฅผ ์ํํ๋ค๊ฐ ๋ค๋ฅธ Thread๋ก ์ ์ด๊ฐ ๋์ด๊ฐ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์๋ง ๋ค๋ฅธ Thread์ ์ํ์๊ฐ๊น์ง ๋ค์ผ๋ก ์ถ๊ฐ๋์ง ์์๊น์? ๋ฐ๋ผ์ ์์์ ์์ฑํ์ ์ฝ๋๋ค์ ์ ํํ ์ํ์๊ฐ์ ์ธก์ ํ์ง ๋ชป ํ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ ๋ค๊ณ ์ ๊ฐ ์ ํํ ์ํ์๊ฐ ์ธก์ ์ ์ํ ์ฝ๋ ์์ฑ ๋ฐฉ๋ฒ์ ์์ง๋ ๋ชปํฉ๋๋ค. -_-;
๋จ, ์ ํํ ์ํ์๊ฐ ์ธก์ ์ ์ํด์๋ผ๋ฉด ์ ๋ฌธ Profiling Tool์ ์ด์ฉํด ๋ณด๋ ๊ฒ์ ์ด๋จ๊น์? NuMega DPS ๊ฐ์ ์ ํ๋ค์ ์ํ์๊ฐ ์ธก์ ์ ์์ฃผ ํธํ๊ฒ ํ ์ ์๊ณ ์ธก์ ๊ฒฐ๊ณผ๋ ์์ค ์ฝ๋ ๋ ๋ฒจ๊น์ง ์ง์ํด ์ค๋๋ค. ๋ง์ ๋ถ๋ก CD์์ ํ๊ฐํ์ ์ฐพ์ ์ ์์ต๋๋ค. ๋จ, ์ฌ์ฉํ์ค ๋ Development Studio ๊ฐ ์กฐ๊ธ ๋ง์ด ๊ฐ๊ฒ๋๋ค. ์ด๊ฑฐ ๋์ค์ NuMega DPS ์ง์ฐ์๋ฉด ์ ์์ผ๋ก ๋์๊ฐ๋๋ค. ๊ทธ๋ผ ์ด๋ง. -- '96 ๋ฐ์ฑ์
p.s. NuMega ์ ํ๋ค์ด ์ด๋ป๊ฒ ์ํ์๊ฐ ์ธก์ ํ๋์ง ์์๋ ๋ถ ๊ธ ์ข ์ฌ๋ ค์ฃผ์์ฃ ?
๋ฉํฐ์ฐ๋ ๋๋ก ์ธํด ์ ์ด๊ถ์ด ๋์ด๊ฐ๋ ๊ฒ๊น์ง ๊ณ ๋ คํด์ผ ํ๋ค๋ฉด ์ฐจ๋ผ๋ฆฌ ๋์ค ๊ฐ์ ์ฑ๊ธํ
์คํน OS์์ ์๊ณ ๋ฆฌ์ฆ ์ํ์๊ฐ์ ๊ณ์ฐํ๋๊ฒ ๋ซ์ง ์์๊น ํ๋ ์๊ฐ๋ ํด๋ด
๋๋ค. (ํ์ง๋ง, ๋ง์ผ TSR ํ๋ก๊ทธ๋จ ๊ฐ์ ๊ฒ์ด ์ธํฐ๋ฝํธ ๊ฐ๋ก์ฑ๋ค๋ฉด ์ญ์ ๋ง์ฐฌ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋ฏ..) ๊ทธ๋ฆฌ๊ณ ๋จ์ํ ํ๋ก๊ทธ๋จ์ ๋ณ๋ชฉ๋ถ๋ถ์ ์ฐพ๊ธฐ ์ํ ์ํ์๊ฐ ๊ณ์ฐ์ด๋ผ๋ฉด Visual C++ ์ ์๋ Profiler ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ต๋๋ค. ํด๋น ํจ์๋ค์ ์ํ์๊ฐ๋ค์ ๋ณด์ฌ์ฃผ๋๊น์.