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

📄 speed.c

📁 一个取得 CPU 信息的程序源码 可以获取16位和32位CPU的信息
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************
* C file:  Speed.c... for cpuinf16 DLL
*
*       This program has been developed by Intel Corporation.  
*		You have Intel's permission to incorporate this code 
*       into your product, royalty free.  Intel has various 
*	    intellectual property rights which it may assert under
*       certain circumstances, such as if another manufacturer's
*       processor mis-identifies itself as being "GenuineIntel"
*		when the CPUID instruction is executed.
*
*       Intel specifically disclaims all warranties, express or
*       implied, and all liability, including consequential and
*		other indirect damages, for the use of this code, 
*		including liability for infringement of any proprietary
*		rights, and including the warranties of merchantability
*		and fitness for a particular purpose.  Intel does not 
*		assume any responsibility for any errors which may 
*		appear in this code nor any responsibility to update it.
*
*  * Other brands and names are the property of their respective
*    owners.
*
*  Copyright (c) 1995, Intel Corporation.  All rights reserved.
***************************************************************/
  
#include <windows.h> 
#include <math.h>
#include <stdio.h>
#include <mmsystem.h>
#include <limits.h>    
#include <memory.h>

#include "speed.h"
#include "cpuid.h"

// Tabs set at 4
#define ROUND_THRESHOLD		6

// Tabs set at 4
static struct FREQ_INFO GetCmosCpuSpeed();
static struct FREQ_INFO GetRDTSCCpuSpeed();
static struct FREQ_INFO GetBSFCpuSpeed(ulong cycles);
static unsigned long diffTime64(unsigned long t1Hi, unsigned long t1Low, 
						 unsigned long t2Hi, unsigned long t2Low, 
 					 	 unsigned long *tHi, unsigned long *tLow );

// extern in ASM file
ushort Time_Processor_bsf(void);

/***************************************************************
* LibMain() -- Windows entry procedure for DLLSs
* 
***************************************************************/
int FAR PASCAL _export LibMain(HANDLE hI, WORD wDS, WORD cbHS, LPSTR lpszCL) {
	if (cbHS != 0) 
	
		UnlockData(0);
	
	return 1;
} // LibMain()



/***************************************************************
* WEP() -- Windows exit procedure for the DLLs.
*
***************************************************************/
int FAR PASCAL _export WEP(int nParam) {
	return 1;
} // WEP()



/***************************************************************
* CpurawSpeed() -- Return the raw clock rate of the host CPU.
*
* Inputs:
*	clocks:		0: Use default value for number of cycles
*				   per BSF instruction.
*               -1: Use CMos timer to get cpu speed (DOES NOT WORK FOR WINNT).
*   			Positive Integer: Use clocks value for number
*				   of cycles per BSF instruction.
*
* Returns:
*		If error then return all zeroes in FREQ_INFO structure
*		Else return FREQ_INFO structure containing calculated 
*       clock frequency, normalized clock frequency, number of 
*       clock cycles during test sampling, and the number of 
*       microseconds elapsed during the sampling.
***************************************************************/

unsigned long FAR PASCAL cpurawspeed(int clocks)
{
	struct FREQ_INFO cpu_speed;

	cpu_speed = cpuspeed(clocks);
	return cpu_speed.raw_freq;
}

/***************************************************************
* CpunormSpeed() -- Return the raw clock rate of the host CPU.
*
* Inputs:
*	clocks:		0: Use default value for number of cycles
*				   per BSF instruction.
*               -1: Use CMos timer to get cpu speed.
*   			Positive Integer: Use clocks value for number
*				   of cycles per BSF instruction.
*
* Returns:
*		If error then return all zeroes in FREQ_INFO structure
*		Else return FREQ_INFO structure containing calculated 
*       clock frequency, normalized clock frequency, number of 
*       clock cycles during test sampling, and the number of 
*       microseconds elapsed during the sampling.
***************************************************************/

unsigned long FAR PASCAL cpunormspeed(int clocks)
{
	struct FREQ_INFO cpu_speed;

	cpu_speed = cpuspeed(clocks);
	return cpu_speed.norm_freq;
}

/***************************************************************
* ProcessorCount() -- Return the number of CPU's on this machine.
*
* Inputs:
*
* Returns:
*		 always 1 for 16 bit dll
***************************************************************/

unsigned long FAR PASCAL ProcessorCount()
{
	return 1;
}

/***************************************************************
* CpuSpeed() -- Return the raw clock rate of the host CPU.
*
* Inputs:
*	clocks:		NULL: Use default value for number of cycles
*				   per BSF instruction.
*   			Positive Integer: Use clocks value for number
*				   of cycles per BSF instruction.
*
* Returns:
*		If error then return all zeroes in FREQ_INFO structure
*		Else return FREQ_INFO structure containing calculated 
*       clock frequency, normalized clock frequency, number of 
*       clock cycles during test sampling, and the number of 
*       microseconds elapsed during the sampling.
***************************************************************/

struct FREQ_INFO FAR PASCAL cpuspeed(int clocks) 
{
	ulong  cycles;					// Clock cycles elapsed 
									//   during test
	
	ushort processor = wincpuid();	// Family of processor

	DWORD features = wincpufeatures();	// Features of Processor
	
	int manual=0;			// Specifies whether the user 
							//   manually entered the number of
							//   cycles for the BSF instruction.

	struct FREQ_INFO cpu_speed;		// Return structure for
									//   cpuspeed
					
	// Number of cycles needed to execute a single BSF 
	//   instruction. Note that processors below i386(tm) 
	//   are not supported.
	ushort processor_cycles[] = {
		00,  00,  00, 115, 47, 43, 
		38,  38,  38, 38,  38, 38, 
	};

	memset(&cpu_speed, 0x00, sizeof(cpu_speed));
	
	if ( processor & CLONE_MASK )
		return cpu_speed;

	// Check for manual BSF instruction clock count
	if (0 <= clocks) {
		cycles =ITERATIONS*(ulong)processor_cycles[processor];
	}
	else if (0 < clocks && clocks <= MAXCLOCKS)  {
		cycles = ITERATIONS * (ulong) clocks;
		manual = 1;			// Toggle manual control flag.
							//   Note that this mode will not
							// 	 work properly with processors
							//   which can process multiple
							//   BSF instructions at a time.
							//   For example, manual mode
							//   will not work on a 
							//   PentiumPro(R)
	}

	if ( ( features&0x00000010 ) && !(manual) ) {
		if ( clocks == 0 )
			return GetRDTSCCpuSpeed();
		else
			return GetCmosCpuSpeed();	
    }
	else if ( processor >= 3 ) {
		return GetBSFCpuSpeed(cycles);
	}        
 
	return cpu_speed;
   	
} // cpuspeed()



static struct FREQ_INFO GetBSFCpuSpeed(ulong cycles)
{
 	ulong  ticks;	// Microseconds elapsed 								//   during test
	ulong freq;		// Most current frequ. calculation
	int i;			// Temporary Variable

	ulong current = 0;      // Variable to store time
							//   elapsed during loop of
							//   of BSF instructions

	ulong lowest  = ULONG_MAX;	// Since algorithm finds 
								//   the lowest value out of
								//   a set of samplings, 
								//   this variable is set 
								//   intially to the max 
								//   unsigned long value). 
								//   This guarantees that 
								//   the initialized value 
								//   is not later used as 
								//   the least time through 
								//   the loop.

	struct FREQ_INFO cpu_speed;		// Return structure for
									//   cpuspeed
					
	memset(&cpu_speed, 0x00, sizeof(cpu_speed));
	
	for ( i = 0; i < SAMPLINGS; i++ ) {
								// Sample SAMPLINGS times. 
								//   Can be increased or 
								//   decreased depending
								//   on accuracy vs. time
								//   requirements

			
		current = Time_Processor_bsf();
           
		if ( current < lowest )		// Take lowest elapsed
			lowest = current;		//   time to account
									//   for some samplings
									//   being interrupted
									//   by other operations 
	}

	ticks = lowest;				
		
		
	// 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 / 119318;		// Convert hundred 
       							//   thousandths of ticks to
       							//   microseconds (us)
        
    if ( (ticks%119318) >= 119318/2 )
       	ticks++;				// Round up if necessary
        	
    freq = cycles/ticks;		// Cycles / us  = MHz

	cpu_speed.raw_freq  = freq;
    if ( cycles%ticks > ticks/2 )
       	freq++;					// Round up if necessary

	cpu_speed.in_cycles = cycles;	// Return variable structure
	cpu_speed.ex_ticks  = ticks;	//   determined by one of 
	cpu_speed.norm_freq = freq;

	return cpu_speed;
}			

static struct FREQ_INFO GetRDTSCCpuSpeed()

⌨️ 快捷键说明

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