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