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

📄 speed.c

📁 一个取得 CPU 信息的程序源码 可以获取16位和32位CPU的信息
💻 C
📖 第 1 页 / 共 2 页
字号:
{
 	ulong  total_ticks=0, ticks;	// Microseconds elapsed 
									//   during test
	
	ulong  total_cycles=0, cycles;	// Clock cycles elapsed 
									//   during test
	
	ulong  stamp0, stamp1;			// Time Stamp Variable 
									//   for beginning and end 
    
    ushort u0,u1;     		        // 16-bit variables for time
    ushort v0,v1;					//   stamp reads. These are 
    								//   later merged into 
    								//   stamp0, and stamp1 
    								//   (32-bit variables)

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

	int manual=0;			// Specifies whether the user 
							//   manually entered the number of
							//   cycles for the BSF instruction.

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

	struct FREQ_INFO cpu_speed;		// Return structure for
									//   cpuspeed
					
    DWORD t0,t1;                   	// Variables to store 
    								//   timeGetTime values

	memset(&cpu_speed, 0x00, sizeof(cpu_speed));

	// On Pentium Processors or above use 
	//   the Read Time Stamp method which 
	//   compares elapsed time on from the
	//   timeGetTime call with elaped
	//   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 2 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

   		t0 = timeGetTime();
    		
		t1 = t0;		// Set Initial Time

   		while ( t1 - t0 < INITIAL_DELAY ) {
   						// Loop until three ticks have 
   						//   passed	since last read of 
						//	 timeGetTime. This accounts for
						//   overhead later.

			t1 = timeGetTime();
		}					

   		__asm						// Read Time Stamp...
		{                       
			RDTSC
			    
			MOV CL, 16
							
			MOV u0, AX
			OPND32
			SHR	AX,CL
			MOV u1, AX
        }                   
		
		t0 = t1;					// Reset Initial Time
			
  		while ( t1 - t0 < SAMPLING_DELAY ) {
   					  	// Loop until 60 ticks have passed 
   					  	//   since last timeGetTime read. 
   					  	//   This allows for elapsed time
   					  	//   for sampling
    					  	
			t1 = timeGetTime();
		}							
			

   	    __asm						// Read Time Stamp...
		{
			RDTSC
				
			MOV CL, 16
							
			MOV v0, AX
			OPND32
			SHR	AX,CL
			MOV v1, AX
        }                   
		
		stamp0 = (ulong) u1*65536 + u0;
		stamp1 = (ulong) v1*65536 + v0;
						// Move two 16-bit values into one 
						//   32-bit value for the time stamp
						//   read at both the beginning and 
						//   end of the test.
   												
       	cycles = stamp1 - stamp0;	// Number of internal 
       								//   clock cycles is 
       								//   difference between 
       								//   two time stamp 
       								//   readings.

   		ticks = (ulong) t1 - t0;	// Number of external 
   									//   ticks is difference 
   									//   between two 
   									//   timeGetTime reads
		                            
        ticks = ticks * 1000;		// Convert ticks to us 
           							//   (since the 
           							//   timeGetTime
           							//   frequency is 1 
           							//   tick/ms).

		total_ticks += ticks;
		total_cycles += cycles;

		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<MAX_TRIES)&&
	        ((abs(3*(int)freq -(int)total)>3*TOLERANCE)||
	         (abs(3*(int)freq2-(int)total)>3*TOLERANCE)||
	         (abs(3*(int)freq3-(int)total)>3*TOLERANCE)));	
					// 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++;

	cpu_speed.raw_freq = total_cycles / total_ticks;
	cpu_speed.norm_freq = cpu_speed.raw_freq;

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

	cpu_speed.ex_ticks = total_ticks;
	cpu_speed.in_cycles = total_cycles;

	return cpu_speed;
}    


static int GetCmosTick(void)
{
	int tick = 0;

	// __asm	mov ah, 02h
	// __asm	int 1Ah
	// __asm	mov al, dh
	// __asm	and ax, 000Fh  

	__asm  xor ax, ax
	__asm  out 070h, al

	__asm  xor ax, ax
	__asm  in  al, 071h

    // _outp( 0x70, offset );
    // base = _inp( 0x71 ); 

// value returned in ax by function

	__asm 	mov word ptr tick, ax

	return tick;
}


//#define ABS_TICK(a,b)  (b<a)?b+60-a:b-a
// since I am only interested in single ticks
#define ABS_TICK(a,b)  (b<a)?b+10-a:b-a

static struct FREQ_INFO GetCmosCpuSpeed()
{
	int	timeStart, timeStop, lapseTime;
	unsigned long   temp;
	unsigned long   temp1;
	struct FREQ_INFO cpu_speed;
	unsigned long   cpuSpeed = 0l;
	ulong  stamp0, stamp1;			// Time Stamp Variable 
									//   for beginning and end 
    
    ushort u0,u1;     		        // 16-bit variables for time
    ushort v0,v1;					//   stamp reads. These are 
    								//   later merged into 
    								//   stamp0, and stamp1 
    								//   (32-bit variables)

	memset(&cpu_speed, 0x00, sizeof(cpu_speed));

	// This loop waits for the next tick
	// so that we begin speed test on a tick edge
	timeStart = GetCmosTick();
	for(;;)
	{
		timeStop = GetCmosTick();
		if (  ABS_TICK(timeStart,timeStop) > 0 )
		{
			__asm						// Read Time Stamp...
			{                       
				RDTSC
			    
				MOV CL, 16
							
				MOV u0, AX
				OPND32
				SHR	AX,CL
				MOV u1, AX
			}                   
			break;	
		}	
	}

	timeStart = timeStop;

	for(;;)
	{
		timeStop = GetCmosTick();
		if (  ABS_TICK(timeStart,timeStop) > 0 )
		{
			__asm						// Read Time Stamp...
			{
				RDTSC
				
				MOV CL, 16
							
				MOV v0, AX
				OPND32
				SHR	AX,CL
				MOV v1, AX
	        }                   
			break;	
		}	
	}

	// convert into long values
	stamp0 = (ulong) u1*65536 + u0;
	stamp1 = (ulong) v1*65536 + v0;

	lapseTime = ABS_TICK(timeStart,timeStop);

	cpuSpeed = stamp1 - stamp0; ///lapseTime; 
	cpu_speed.in_cycles = cpuSpeed;		// Cycles count since we in this routine

	//round to nearest digit
	temp =  cpuSpeed/1000000; 	
	temp1 = cpuSpeed/100000;  
	temp = temp * 10;  // realign with last digit = zero

	cpuSpeed = cpuSpeed/1000000; // cpuSpeed/1000000;
	cpu_speed.raw_freq = cpuSpeed;	

	if( (temp1 - temp) >= ROUND_THRESHOLD )
		cpuSpeed++;
	
	cpu_speed.norm_freq = cpuSpeed;	
	cpu_speed.ex_ticks = (timeStop - timeStart) * 1000000;

	return cpu_speed;			
}

⌨️ 快捷键说明

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