手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

CPU 测速(MHz)和高精度延时(微秒级)

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

一.高精度延时, 是 CPU 测速的基础
Windows 内部有一个精度很高的定时器, 精度在微秒级, 但不同的系统这个定时器的频率不同, 这个频率和硬件和操作系统都可能有关。

利用 API 函数 QueryPerformanceFrequency 能够得到这个定时器的频率。
利用 API 函数 QueryPerformanceCounter 能够得到定时器的当前值。
根据要延时的时间和定时器的频率, 能够算出要延时的时间定时器经过的周期数。
在循环里用 QueryPerformanceCounter 不停的读出定时器值, 一直到经过了指定周期数再结束循环, 就达到了高精度延时的目的。

高精度延时的程式, 参数: 微秒:

void DelayUs(__int64 Us)
{
LARGE_INTEGER CurrTicks, TicksCount;

QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);

TicksCount.QuadPart = TicksCount.QuadPart * Us / 1000000i64;
TicksCount.QuadPart = CurrTicks.QuadPart;

while(CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);
}

二.测速程式
利用 rdtsc 汇编指令能够得到 CPU 内部定时器的值, 每经过一个 CPU 周期, 这个定时器就加一。
假如在一段时间内数得 CPU 的周期数, CPU工作频率 = 周期数 / 时间

为了不让其他进程和线程打扰, 必需要配置最高的优先级
以下函数配置当前进程和线程到最高的优先级。
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

CPU 测速程式的源代码, 这个程式通过 CPU 在 1/16 秒的时间内经过的周期数计算出工作频率, 单位 MHz:

int CPU_Frequency(void) //MHz
{
LARGE_INTEGER CurrTicks, TicksCount;
__int64 iStartCounter, iStopCounter;

DWORD dwOldProcessP = GetPriorityClass(GetCurrentProcess());
DWORD dwOldThreadP = GetThreadPriority(GetCurrentThread());

SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);

TicksCount.QuadPart /= 16;
TicksCount.QuadPart = CurrTicks.QuadPart;

asm rdtsc
asm mov DWORD PTR iStartCounter, EAX
asm mov DWORD PTR (iStartCounter 4), EDX

while(CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);

asm rdtsc
asm mov DWORD PTR iStopCounter, EAX
asm mov DWORD PTR (iStopCounter 4), EDX

SetThreadPriority(GetCurrentThread(), dwOldThreadP);
SetPriorityClass(GetCurrentProcess(), dwOldProcessP);

return (int)((iStopCounter-iStartCounter)/62500);
}

前面是用 API 函数进行延时, 假如知道了 CPU 的工作频率, 利用循环, 也能够得到高精度的延时

int _CPU_FREQ = 0; //定义一个全局变量保存 CPU 频率 (MHz)

void CpuDelayUs(__int64 Us) //利用循环和 CPU 的频率延时, 参数: 微秒
{
__int64 iCounter, iStopCounter;

asm rdtsc
asm mov DWORD PTR iCounter, EAX
asm mov DWORD PTR (iCounter 4), EDX

iStopCounter = iCounter Us*_CPU_FREQ;

while(iStopCounter-iCounter>0)
{
asm rdtsc
asm mov DWORD PTR iCounter, EAX
asm mov DWORD PTR (iCounter 4), EDX
}
}

void TestDelay(void)
{
_CPU_FREQ = CPU_Frequency(); //利用 CPU 频率初始化定时
CpuDelayUs(1000000); //延时 1 秒钟
}




文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS