E D R , A S I H C RSS

Performance Test

ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•. ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์„ฑ๋Šฅ์„ ์•Œ์•„๋ณด๋Š” ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜๊ฐ€ ์ˆ˜ํ–‰์‹œ๊ฐ„ ์ธก์ •์ž…๋‹ˆ๋‹ค.

HighResolutionTimer ์‚ฌ์šฉํ•˜๊ธฐ

Windows ์—์„œ์˜ ์ˆ˜ํ–‰์‹œ๊ฐ„์ธก์ • ๋ฐฉ๋ฒ•.
~cpp 
 BOOL QueryPerformanceFrequency(LARGE_INTEGER* param)
 BOOL QueryPerformanceCounter(LARGE_INTEGER* param)
์ƒ๊ธฐ ๋‘ Windows APIํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์„ ์ธก์ • ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ

์ˆ˜ํ–‰์‹œ๊ฐ„ ์ธก์ •์šฉ C++ Class. ์ˆ˜ํ–‰์‹œ๊ฐ„ ๋‹จ์œ„๋Š” Sec ์ž…๋‹ˆ๋‹ค. ๋‹จ HighResolutionTimer๋ฅผ ์ง€์›ํ•˜๋Š” ํ”„๋กœ์„ธ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
๋‹ค์Œ์€ 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๋„ ์ด ๋ช…๋ น์„ ์ด์šฉํ•ด ๊ตฌํ˜„ํ•œ ๊ฒƒ์œผ๋กœ ์ถ”์ธก๋œ๋‹ค. ์ธ๋ผ์ธ ์–ด์…ˆ๋ธ”๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
~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 ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์˜ ์ˆ˜ํ–‰์‹œ๊ฐ„๋“ค์„ ๋ณด์—ฌ์ฃผ๋‹ˆ๊นŒ์š”.

NuMaga DPS ๋ฉด Dev-Partner Studio ๋ง์”€์ธ๊ฐ€ ๋ณด์ฃ ? (์ „์— Bound Checker ์†Œ๋ฌธ๋งŒ ๋“ค์–ด๋ด์„œ..~) --1002
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:00
Processing time 0.0061 sec