今天,我的生活很简单。我就是伸了伸手掌,测了测我的内存,掂了掂我的CPU使用率。今天,我的思维就钻到计算机里,给绞了。CPU型号和逻辑硬盘都在我的手指边,随手就可以碰触。
今天,我写的博客不针对搜索引擎。不去迎合它的喜好,没有罗列关键词,也没有写一个好的Title。
CPU使用率
计算CPU使用率要借用NtQuerySystemInformation函数。从SystemPerformanceInformation中得到空闲时间;从SystemTimeInformation中得到系统时间;从SystemBasicInformation中得到进程数。CPU使用率的公式就是:CpuUsageInPercent = 100 – (CpuTime[n] – CpuTime[n-1]) / (SystemTime[n] – SystemTime[n-1]) / NumberOfProcessors * 100。这种方法可在Windows NT/2000系统中使用。
另外,还有一种得到CPU使用率的方法。GetSystemTimes函数可以得到idleTime, kernelTime, userTime。由此也可以得到CPU使用率,程序如下:
#define _WIN32_WINNT 0×0501
#include
#include
using namespace std;
__int64 CompareFileTime ( FILETIME time1, FILETIME time2 )
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime ;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime ;
return (b – [...]
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG [...]
一、存储结构
按照软件设计的思想,程序包括数据和建立在数据上的操作。在设计该计算机系统的时候也主要考虑的是数据(程序、操作数和微指令)的存储方式和要对数据完成的操作。经过对器件和性能的综合考虑,最后决定系统总体结构采用类似哈佛结构。其主要特点如下:
1、使用两个独立的存储器模块,分别存储指令和数据,每个存储模块都不允许指令和数据并存;
2、指令存储器和数据存储器使用独立的两条总线,分别作为CPU与每个存储器之间的专用通信路径,这两条总线之间毫无关联;
3、微指令共约十一位,按高低位分开存储在两个存储器,可一次读出完整的微指令,剩余约五位控制位做为扩展;
4、微指令分开存在指令存储器和数据存储器中,数据总线采用分时共用的原则,高电平时读取微指令,低电平时才读取指令和数据。
二、流水线
完成一条指令一般需要三个步骤:取指令、指令译码和执行指令。其中在取指令和执行指令阶段都有访存的操作,对于冯.诺曼结构,由于取指令和存取数据要从同一个存储空间存取,经由同一总线传输,因而它们无法重叠执行。但是采用哈佛结构,相当于利用重复设置资源的方式消除了瓶颈段,这两个执行部件的可以同时访存互不干扰,因而可以重叠执行。流水线重叠执行过程如下表:
指令1
取指令
译码
执行
指令2
取指令
译码
执行
指令
取指令
译码
执行
其中,译码在时钟周期的高电平期间完成;执行指令和取下一条指令在时钟周期的低电平期间完成。由于译码期间的访存,以及执行指令和取下一条指令期间的访存,存在对总线的复用,所以无法形成更深程度的流水线。
三、指令系统
以运算器为中心,包括各寄存器和数据存储器的操作都由控制器集中控制,控制器又由时钟信号控制。时钟信号就是整个系统的幕后黑手,按周期动作,有条不紊。在指令和微指令的设计过程中,为了保证流水线的正常运行,就要尽量保证指令的规整而且要保证每条指令都在一个时钟周期内完成。所以,该指令系统主要特点如下:
1、指令共八位,高四位为操作码,低四位为操作数地址;
2、大多数指令操作数有两位,一位由AC提供,另一位由存储器直接提供操作数地址由指令低四位给出;
3、每次计算的结果都由保存在DR中,并设计专门的指令把结果送往寄存器AC或送往存储器;
4、设计一条空指令,每用一次跳转指令就要紧跟一条空指令,因为没有设置动态分支预测或硬件自动插入“气泡”的机制。
部分指令和微指令列表如下:
S3
S2
[...]
介绍一个我用VHDL写的RISC-CPU程序,这个程序实现一个16位CPU。该CPU使用精减指令集,是一个五段流水线的结构。包括取指令(IF)、读寄存器(RD)、运算器(ALU)、内存读写(MEM)和写回(WB)。系统时序图如下:
各段的功能和完成的操作如下:
1、IF段把PC值送地址位,并读出指令。该还完成PC修改,加1或者跳转,受RD段结构冲突信号和MEM跳转信号控制。
2、RD段把指令中的寄存器读出,负责寄存器重命名,并把操作数准备好的指令送ALU。这个过程可以实现指令乱续执行。
3、ALU完成计算。
4、MEM段只有lode-store指令和跳转指令动作,其它指令直接通过。把需要写结果的指令送往下一站。
5、WB段把结果写回。该段没有做成一个专门的部件,而是和RD段做在一起。寄存器对其它段是“不可见的”。
所有操作过程都是先准备好数据和控制操作码,等时钟信号到来然后再执行。可以把图中虚线当作时钟下降沿。关于时序设计的注意点:
1、提高CPU性能的问题可归结为如何规划系统时序以获得尽可能小的CPI和尽量大的稳定工作频率。
2、混合时钟沿电路是指一部分部件在时钟上升沿动作,另一部分部件在时钟下降沿动作。在控制器的设计中,可以将控制信号的发出与执行部件的动作隔开半个时钟周期,即控制信号在时钟下降沿发出,而执行部件在下个时钟上升沿动作。
3、在数字系统中,时序规划往往决定了系统性能,设计时应尽可能满足同步原则。一方面要尽可能使整个系统同步于单一时钟,即使不得不涉及多时钟域也应做到局部同步,避免使用门控时钟;另一方面要避免使用混合时钟沿电路,而改用满足同步原则的单一时钟沿电路代替。
4、对于如CPU这样的复杂逻辑系统,时序设计的好坏成为影响系统性能的一个重要因素。在设计具体电路前,必须对系统时序做一个整体规划,才能避免因对信号间时序关系理解不充分而导致设计错误的危险。基于上述理由,甚至可以说RTL级设计实际上只是一场时序的游戏。
下面提供程序的下载。该程序多数FPGA都能通过,低端FPGA需要使用更低的电钟频率,根据存储器的速度也要调整时钟频率。目前大部分结构冲突和数据冲突都测试正确,只在控制冲突下可能出现一个小BUG,还没有进行严格测试(控制冲突时不一定会出错)。
cpu16