Exemplo n.º 1
0
/****************************************************************************
DESCRIPTION:
Returns the speed of the processor in MHz.

HEADER:
cpuinfo.h

PARAMETERS:
accurate    - True of the speed should be measured accurately

RETURNS:
Processor speed in MHz.

REMARKS:
This function returns the speed of the CPU in MHz. Note that if the speed
cannot be determined, this function will return 0.

If the accurate parameter is set to true, this function will spend longer
profiling the speed of the CPU, and will not round the CPU speed that is
reported. This is important for highly accurate timing using the Pentium
RDTSC instruction, but it does take a lot longer for the profiling to
produce accurate results.

SEE ALSO:
CPU_getProcessorSpeedInHz, CPU_getProcessorType, CPU_haveMMX,
CPU_getProcessorName
****************************************************************************/
ulong ZAPI CPU_getProcessorSpeed(
    ibool accurate)
{
#if defined(__INTEL__)
    /* Number of cycles needed to execute a single BSF instruction on i386+
     * processors.
     */
    u64     speed64;
    ulong   cpuSpeed;
    uint    i;
    static  ulong intel_cycles[] = {
        115,47,43,
        };
    static  ulong cyrix_cycles[] = {
        38,38,52,52,
        };
    static  ulong amd_cycles[] = {
        49,
        };
    static  ulong known_speeds[] = {
        2000,1800,1700,1600,1500,1400,1300,1200,1100,1000,950,900,850,800,750,
        700,650,600,550,500,450,433,400,350,333,300,266,233,200,166,150,133,
        120,100,90,75,66,60,50,33,20,0,
        };

    if (CPU_haveRDTSC()) {
        GetRDTSCCpuSpeed(accurate, &speed64);
        PM_div64_32(speed64, speed64, 1000000);
        cpuSpeed = PM_getlo32(speed64);
        }
    else {
        int type = CPU_getProcessorType();
        int processor = type & CPU_mask;
        int vendor = type & CPU_familyMask;
        if (vendor == CPU_Intel)
            cpuSpeed = GetBSFCpuSpeed(ITERATIONS * intel_cycles[processor - CPU_i386]);
        else if (vendor == CPU_Cyrix)
            cpuSpeed = GetBSFCpuSpeed(ITERATIONS * cyrix_cycles[processor - CPU_Cyrix6x86]);
        else if (vendor == CPU_AMD)
            cpuSpeed = GetBSFCpuSpeed(ITERATIONS * amd_cycles[0]);
        else
            return 0;
        }

    /* Now normalise the results given known processors speeds, if the
     * speed we measure is within 2MHz of the expected values
     */
    if (!accurate) {
        for (i = 0; known_speeds[i] != 0; i++) {
            if (cpuSpeed >= (known_speeds[i]-3) && cpuSpeed <= (known_speeds[i]+3)) {
                return known_speeds[i];
                }
            }
        }
    return cpuSpeed;
#else
    return 0;
#endif
}
Exemplo n.º 2
0
struct FREQ_INFO 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

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

    if ( processor & CLONE_MASK )
        return cpu_speed;

    // Check for manual BSF instruction clock count
    if (clocks <= 0) {
        cycles = ITERATIONS * processor_cycles[processor];
    }
    else if (0 < clocks && clocks <= MAXCLOCKS)  {
        cycles = ITERATIONS * 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) ) {
        // On processors supporting the Read
        //   Time Stamp opcode, compare elapsed
        //   time on the High-Resolution Counter
        //   with elapsed cycles on the Time
        //   Stamp Register.
        if ( clocks == 0 )
            return GetRDTSCCpuSpeed();
        else
            return GetCmosCpuSpeed();
    }
    else if ( processor >= 3 ) {
        return GetBSFCpuSpeed(cycles);
    }

    return cpu_speed;

} // cpuspeed()