?? speed.c
字號:
/***************************************************************
* 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 + -