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.0859 sec