⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.cpp

📁 网络泡泡被.net管理
💻 CPP
字号:
#include "stdafx.h"
#include <windows.h>
#include "gslib_internal.h"

 ///	CPCODE 定义
//////////////////////

#define CPU_ID _asm _emit 0x0f _asm _emit 0xa2 	
										// CPUID instruction

#define RDTSC  _asm _emit 0x0f _asm _emit 0x31	
										// RDTSC instruction


DWORD TIMER::CyclePerSec=0;
DWORD TIMER::CP10K=0;
DWORD TIMER::starttime=0;

// 利用 RDTSC 指令获得 CPU 速度 (摘抄并修改自 Intel 开发并公开的自由代码)

#define ROUND_THRESHOLD		6

int TIMER::CPU()
{
	int raw_freq;		// Raw frequency of CPU in MHz
	
	int norm_freq;	// Normalized frequency of CPU
								//   in MHz.
	LARGE_INTEGER t0,t1;			// Variables for High-
									//   Resolution Performance
									//   Counter reads

	DWORD freq  =0;			// Most current frequ. calculation
	DWORD freq2 =0;			// 2nd most current frequ. calc.
	DWORD freq3 =0;			// 3rd most current frequ. calc.
	
	DWORD total;			// Sum of previous three frequency
							//   calculations

	int tries=0;			// Number of times a calculation has
							//   been made on this call to 
							//   cpuspeed

	DWORD  total_cycles=0, cycles;	// Clock cycles elapsed 
									//   during test
	
	DWORD  stamp0, stamp1;			// Time Stamp Variable 
									//   for beginning and end 
									//   of test

	DWORD  total_ticks=0, ticks;	// Microseconds elapsed 
									//   during test
	
	LARGE_INTEGER count_freq;		// High Resolution 
									//   Performance Counter 
									//   frequency

#ifdef WIN32
	int iPriority;
	HANDLE hThread = GetCurrentThread();
#endif // WIN32;

	if ( !QueryPerformanceFrequency ( &count_freq ) )
		return 0;

	// On processors supporting the Read 
	//   Time Stamp opcode, compare elapsed
	//   time on the High-Resolution Counter
	//   with elapsed cycles on the Time 
	//   Stamp Register.
	
	do {			// This do loop runs up to 20 times or
	   				//   until the average of the previous 
	   				//   three calculated frequencies is 
	   				//   within 1 MHz of each of the 
	   				//   individual calculated frequencies. 
					//   This resampling increases the 
					//   accuracy of the results since
					//   outside factors could affect this
					//   calculation
			
		tries++;		// Increment number of times sampled
						//   on this call to cpuspeed
			
		freq3 = freq2;	// Shift frequencies back to make
		freq2 = freq;	//   room for new frequency 
						//   measurement

    	QueryPerformanceCounter(&t0);	
    					// Get high-resolution performance 
    					//   counter time
			
		t1.LowPart = t0.LowPart;		// Set Initial time
		t1.HighPart = t0.HighPart;

#ifdef WIN32
		iPriority = GetThreadPriority(hThread);
		if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
		{
			SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
		}
#endif // WIN32

   		while ( (DWORD )t1.LowPart - (DWORD )t0.LowPart<50) {	  
   						// Loop until 50 ticks have 
   						//   passed	since last read of hi-
						//	 res counter. This accounts for
						//   overhead later.

			QueryPerformanceCounter(&t1);

			RDTSC;						// Read Time Stamp
			_asm {
				MOV stamp0, EAX
			}
		}
			
			
		t0.LowPart = t1.LowPart;		// Reset Initial 
		t0.HighPart = t1.HighPart;		//   Time

   		while ((DWORD )t1.LowPart-(DWORD )t0.LowPart<1000 ) {
   						// Loop until 1000 ticks have 
   						//   passed	since last read of hi-
   						//   res counter. This allows for
						//   elapsed time for sampling.
   			
				
   			QueryPerformanceCounter(&t1);
   			

			RDTSC;						// Read Time Stamp
			__asm {
				MOV stamp1, EAX
			}
		}

			

#ifdef WIN32
		// Reset priority
		if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
		{
			SetThreadPriority(hThread, iPriority);
		}
#endif // WIN32

       	cycles = stamp1 - stamp0;	// Number of internal 
        							//   clock cycles is 
        							//   difference between 
        							//   two time stamp 
        							//   readings.

    	ticks = (DWORD ) t1.LowPart - (DWORD ) t0.LowPart;	
								// Number of external ticks is
								//   difference between two
								//   hi-res counter reads.
	

		// Note that some seemingly arbitrary mulitplies and
		//   divides are done below. This is to maintain a 
		//   high level of precision without truncating the 
		//   most significant data. According to what value 
		//   ITERATIIONS is set to, these multiplies and
		//   divides might need to be shifted for optimal
		//   precision.

		ticks = ticks * 100000;	
							// Convert ticks to hundred
							//   thousandths of a tick
			
		ticks = ticks / ( count_freq.LowPart/10 );		
							// Hundred Thousandths of a 
							//   Ticks / ( 10 ticks/second )
							//   = microseconds (us)

		total_ticks += ticks;
		total_cycles += cycles;

		if ( ticks%count_freq.LowPart > count_freq.LowPart/2 )
			ticks++;			// Round up if necessary
			
		freq = cycles/ticks;	// Cycles / us  = MHz
        										
     	if ( cycles%ticks > ticks/2 )
       		freq++;				// Round up if necessary
          	
		total = ( freq + freq2 + freq3 );
							// Total last three frequency 
							//   calculations

	} while ( (tries < 3 ) || 		
	          (tries < 20)&&
	          ((abs(3 * freq -total) > 3 )||
	           (abs(3 * freq2-total) > 3 )||
	           (abs(3 * freq3-total) > 3 )));	
					// Compare last three calculations to 
	          		//   average of last three calculations.		

	// Try one more significant digit.
	freq3 = ( total_cycles * 10 ) / total_ticks;
	freq2 = ( total_cycles * 100 ) / total_ticks;


	if ( freq2 - (freq3 * 10) >= ROUND_THRESHOLD )
		freq3++;

	CP10K= (int) ((double)total_cycles / total_ticks * 100);
	CyclePerSec = CP10K * 10000;
	raw_freq = total_cycles / total_ticks;
	norm_freq = raw_freq;

	freq = raw_freq * 10;
	if( (freq3 - freq) >= ROUND_THRESHOLD )
		norm_freq++;

	return norm_freq;
}

// 返回时间
DWORD TIMER::time()
{
	union {
		unsigned __int64 time;
		struct {
			DWORD low;
			DWORD high;
		};
	} timer;

	RDTSC;
	__asm {
		mov timer.low,eax;
		mov timer.high,edx;
	}

	return DWORD(timer.time / CP10K) - starttime;
}

// 时间检测 (set==0 开启, set==1 关闭)
DWORD TIMER::timer(int set)
{
	static int iPriority;
	static HANDLE hThread;
	static struct {
			DWORD low;
			DWORD high;
		} timer,tmp;
	if (set==0) {
		hThread	= GetCurrentThread();		
		iPriority = GetThreadPriority(hThread);
		if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
		{
			SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
		}

		RDTSC;
		__asm {
			mov timer.low,eax;
			mov timer.high,edx;
		}
		return 0;
	}
	else {
		RDTSC;
		__asm {
		  sub eax,timer.low;
		  sbb edx,timer.high;
		  shrd eax,edx,3;
		  shr edx,3;
		  mov timer.low,eax;
		  mov timer.high,edx;
		}

		// Reset priority
		if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
		{
			SetThreadPriority(hThread, iPriority);
		}

		if (timer.high>0) return 0;
	}
	return timer.low;  
}

void TIMER::reset()
{
	union {
		unsigned __int64 time;
		struct {
			DWORD low;
			DWORD high;
		};
	} timer;

	RDTSC;
	__asm {
		mov timer.low,eax;
		mov timer.high,edx;
	}

	starttime = (DWORD) (timer.time / CP10K);
}

int TIMER::init()
{
	CPU();
	reset();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -