编程获得CPU的主频

原创 2014年05月09日 14:37:53

CPU的主频,即CPU内核工作的时钟频率(CPU Clock Speed)。CPU的主频表示在CPU内数字脉冲信号震荡的速度。主频和实际的运算速度存在一定的关系,但目前还没有一个确定的公式能够定量两者的数值关系,因为CPU的运算速度还要看CPU的流水线的各方面的性能指标(缓存、指令集,CPU的位数等等)。由于主频并不直接代表运算速度,所以在一定情况下,很可能会出现主频较高的CPU实际运算速度较低的现象。

windows操作系统中,可以使用右键点击“我的电脑”,查看属性来获取CPU的主频信息,然而该信息是存在于注册表之中的。也就是说可以通过修改注册表来伪造CPU主频信息。那能不能用其它方法获得该信息呢?

检测CPU的速度,一般是测试在单位时间内运算的指令条数,但用这种方法有太大的局限性,由于受到很多因素的影响,准确度比较低,因为你不知道在你的程序外别的程序占用了多少的时间片。其实在586及之后处理器中,已经有了一条专用的指令来测试主频,那就是 RDTSC指令,意思是读取时间标记计数器(Read Time-Stamp Counter)Time-stamp counter 是处理器内部的一个64位的MSR (model specific register),处理器每时钟周期递增时间标签计数器 MSR 一次,在处理器复位时将它重设为 0RDTSC 指令把 TSC的值低32位装入EAX中,高32位装入EDX中。如果CPU的主频是200MHz,那么在一秒钟内,TSC的值增加 200,000,000 次。所以在计算的时候,把两次的TSC差值除以两次的时间差值就是CPU的主频。

从上面的资料得到了一个思路:首先使用RDTSC指令获取1TSC的值,将其存储起来,再延时1秒,使用RDTSC指令获取1个新的TSC值,并用其减去第一次获得的TSC值,即可得到该CPU的主频。用C和汇编混合的代码如下:

#include <windows.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	static int time[2];
	int quotient = 0; //商
	int remainder = 0; //余数

	__asm{
		rdtsc // read time-stamp count
		mov ebx,offset time //将time的偏移地址存入ebx
		mov [ebx+0],edx //把TSC的值的高32位存入[ebx+0]中
		mov [ebx+4],eax //把TSC的值的低32位存入[ebx+4]中
	}
	Sleep(1000);
	__asm{
		rdtsc // read time-stamp count
		mov ecx,offset time //将time的偏移地址存入ecx
		sub eax,[ecx+4] //把延时1秒后的TSC值的低32位减去1秒前的TSC值的低32位
		sbb edx,[ecx+0] //把延时1秒后的TSC值的高32位减去1秒前的TSC值的高32位

		mov ecx,1000000000 //转换成GHz
		div ecx
		mov quotient,eax //将结果中的商赋值于quotiend
		mov remainder,edx //将结果中的余数赋值于remainder
	}
	remainder = remainder / 10000000; //余数仅保留两位
	printf("该机主频为:%d.%d",quotient,remainder);
	return 0;
}

注意:寄存器 CR4 中的时间标签禁用 (TSD) 标志限制 RDTSC 的使用。清除 TSD 标志时,RDTSC 指令可以在任何特权级别执行;设置此标志时,指令只能在特权级别 执行。在特权级别 执行时,时间标签计数器还可以使用 RDMSR 指令读取。

但是在多核时代,RDTSC 指令的准确度大大削弱了,原因有如下几点: 

1. 不能保证同一块主板上每个核的 CPU 时钟周期数(Time Stamp Counter)是同步的; 

2. CPU 的时钟频率可能变化,例如笔记本电脑的节能功能; 

3. 乱序执行导致 RDTSC 测得的周期数不准。 虽然 RDTSC 废掉了,高精度计时还是有办法的,在 Windows 上用 QueryPerformanceCounter 和 QueryPerformanceFrequencyLinux 上用 POSIX 的 clock_gettime 函数,以 CLOCK_MONOTONIC 参数调用。

在接下来的几篇文章章中,我会继续介绍相关内容。

参考文章:

1、多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间

http://blog.csdn.net/solstice/article/details/5196544

2、RDTSC命令详解

http://blog.csdn.net/tbwood/article/details/5536597

如何获取CPU的主频和使用率?

最近看到论坛中有人需要在Java端读取系统的CPU主频和使用率,在网上搜索了一下,发现了一些有用的东西,就在这总结一下。一、获得CPU的主频1、从注册表中读取在注册表中键HKLM/HARDWARE/D...
  • dawn023
  • dawn023
  • 2009年04月08日 16:20
  • 3817

CPU主频监控-cpufrequtils

  • 2017年11月05日 13:00
  • 35KB
  • 下载

Linux内核中CPU主频和电压调整 (二)

CPUfreq core 和notifier 概述 简介 CPUFreq核心代码位于kernel/drivers/cpufreq/cpufreq.c. 该代码提供了一个针对CPUFreq...

cpu技术,主频,外频

  • 2009年07月29日 17:47
  • 18KB
  • 下载

CPU主频越高性能

  • 2012年04月07日 16:24
  • 17KB
  • 下载

CPU性能的影响因素:主频和架构

主频和架构对CPU性能的影响同样重要,不能够割裂这两个因素来评估CPU的性能。 主频很容易理解,类似于速度,对于同一种架构的CPU,当然是主频越高CPU的速度就越快。 但是,如果CPU的架构不一样,只...

CPU-主频与制程

  • 2014年07月24日 10:49
  • 41KB
  • 下载

世界上最小的台式机“树莓派”,CPU主频有点小

一、产品综述 Raspberry Pi(中文名为“树莓派”,简写为RPi,或者RasPi/RPi)是为孩童计算机编程教育而设计,只有信用卡大小的卡片式电脑,其系统基于Linux。它由注册于英国的慈善...

使用cpufreq给CPU临时调整主频

使用cpufreq给CPU临时调整主频 现代的CPU和主板都有节电技术,在CPU低负荷工作的会自动降频。如果需要临时设置主频和工作模式,可使用cpufreq手动调整。这个模式将在重启...
  • tengh
  • tengh
  • 2013年07月24日 14:50
  • 1074
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编程获得CPU的主频
举报原因:
原因补充:

(最多只允许输入30个字)