操作系统  办公  实用知识  设计  开发  WEB开发  移动开发  数据库  软件工程  网管  安全  管理  信息化  答疑  渠道 

如何检测CPU的主频

2003-10-26 网友评论 0 条 点击进入论坛

概述:

    说到检测CPU的速度,一般是测试在单位时间内运算的指令条数,但用这种方法有太大的局限性,由于受到很多因素的影响,准确度比较低,特别是在Windows环境下,你不知道在你的程序外别的程序占用了多少的时间片。其实,在586及以上档次处理器中,已经有了一条专用的指令来测试主频,那就是 RDTSC指令,意思是读取时间标记计数器(Read Time-Stamp Counter),Time-stamp counter 是处理器内部的一个64位的MSR (model specific register),它每个时钟增加一个记数。在处理器复位的时候,初始值为0,RDTSC 指令把 TSC的值低32位装入EAX中,高32位装入EDX中。如果CPU的主频是200MHz,那么在一秒钟内,TSC的值增加 200,000,000 次。所以在计算的时候,把两次的TSC差值除以两次的时间差值就是CPU的主频。
    程序的结构如下: 初始化的时候设置一个定时器,定时时间为1秒,然后在定时器消息中利用 RDTSC 取得 TSC计数,再和上次保留的值相减,然后除以时间差即可。

源程序:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Programmed by 罗云彬, bigluo@telekbird.com.cn
; Website: http://asm.yeah.net
; LuoYunBin''s Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 版本信息
; CPU 频率 - 利用586指令 rdtsc 计算CPU的频率
;    V1.0 ------ 2000年6月21日
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  .586
  .model flat, stdcall
  option casemap :none   ; case sensitive

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include  windows.inc
include  user32.inc
include  kernel32.inc
include  comctl32.inc
include  comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

DLG_MAIN equ  1000
ID_SPEED equ  1001

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  .data?

dwTickCount dd ?
dwTSC  dd ?,?
hInstance dd ?
szBuffer db 256 dup (?)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD

  .data

szSpeed  db "你的CPU主频为 %d MHz",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  .code

include  Win.asm

;********************************************************************
_ProcDlgMain proc uses ebx edi esi, \
  hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
  local @stPoint:POINT
  local @hWindow

  mov eax,wMsg
  .if eax == WM_CLOSE
   invoke EndDialog,hWnd,NULL
   invoke KillTimer,hWnd,1
  .elseif eax == WM_INITDIALOG
   invoke _CenterWindow,hWnd
   invoke GetTickCount  ;TSC 初始值
   mov dwTickCount,eax

   rdtsc
   mov dwTSC,eax
   mov dwTSC+4,edx
   invoke SetTimer,hWnd,1,1000,NULL
  .elseif eax == WM_TIMER
   invoke GetTickCount
   push eax
   sub eax,dwTickCount
   pop dwTickCount
   push eax

   rdtsc
   push edx
   push eax
   sub eax,dwTSC
   sbb edx,dwTSC+4
   pop dwTSC
   pop dwTSC+4

   mov ecx,1000000
   div ecx   ;除以1Mhz=1000000hz
   .if edx >= 500000h  ;四舍五入
    inc eax
   .endif
   mov ecx,1000
   mul ecx   ;1秒=1000毫秒
   pop ecx   ;pop出经过的毫秒数
   div ecx

   invoke wsprintf,offset szBuffer,offset szSpeed,eax
   invoke SendDlgItemMessage,hWnd,ID_SPEED,\
    WM_SETTEXT,0,offset szBuffer
  .else
;********************************************************************
; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
; 要返回 FALSE
;********************************************************************
   mov eax,FALSE
   ret
  .endif    
  mov eax,TRUE
  ret
  
_ProcDlgMain endp
;********************************************************************
start:
  invoke GetModuleHandle,NULL
  mov hInstance,eax
  invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
  invoke ExitProcess,NULL

  end start

已有 0 位对此文章感兴趣的网友发布了看法    
我来评两句 登录邮箱: 密码:
  匿名发表
今日推荐
技术文库(共有 46430 篇文章)
操作系统
办公软件
实用知识
网络管理
软件开发
WEB开发
软件工程
数据库
设计在线
信息安全
行业信息化
管理信息化
重点推荐
电子杂志订阅
点击电子杂志名称查看样刊
输入E-mail地址即可订阅
E-mail