怎样测CPU的主频?

lanzhengpeng2 2002-12-20 09:06:08
由于别人可以通过修改注册表或截获系统函数,是我无法信任我得到的结果,所以,最好能介绍一种独立的测试方法
...全文
77 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
gridcomputing 2002-12-22
  • 打赏
  • 举报
回复
我很佩服罗大哥。
IT-司马青衫 2002-12-22
  • 打赏
  • 举报
回复
┏━━━━━━━━━━━━━┓
┃※※※※★★★★★※※※※┃
┃※【终级掠食者—大白鲨】※┃
┃※※※※★★★★★※※※※┃
┗━━━━━━━━━━━━━┛

假如我回答你满意;
在结帐时请整理FAQ;
以便增加我的信誉分
IT-司马青衫 2002-12-22
  • 打赏
  • 举报
回复
概述:

说到检测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
lanzhengpeng2 2002-12-22
  • 打赏
  • 举报
回复
首先多谢各位的捧场。但是,你们看了标题后也看看我的内容啊:
————————————
由于别人可以通过修改注册表或截获系统函数,是我无法信任我得到的结果
————————————
ehom(?!)利用sleep本身就非常不准确,而且需要至少18.2ms以上的时间才能测到结果。
bigwhiteshark(大白鲨_曾牧暗鲨_海阔任鲨游)的SetTimer也非常不准确。
总而言之,我不能信任操作系统提供的信息!

谁有办法?分不是问题,而且有满意答案我必然整理FAQ!
ahalf 2002-12-21
  • 打赏
  • 举报
回复
intel提供专门的测试工具
ehom 2002-12-20
  • 打赏
  • 举报
回复
function GetCPUSpeed: Integer;
const
DelayTime = 500;
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
try
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := Round(TimerLo / (1000.0 * DelayTime));
except
Result := 0;
end;
end;

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧