最近在看编程之美,看到第一个问题时,一下子就被吸引了,原来在windows 的任务管理器中还可以让CPU舞动起来,再一次的相信了编程中只有想不到没有做不到,对于书中的做法和网上的实现大致都相同,不过在看后面的解法之前,我的解法和书中第一种简单的控制之法相同,而且我还引入了一个实时监测CPU主频的函数,可以移植到其他的PC上。
#include <windows.h> #include <iostream> using namespace std; int size = 0; int getCPUFrequency() { static int time[2]; //定义一个整型数组time int a = 0; //定义整形变量a=0(在后面的运算中用来存商) int b = 0; //定义整形变量b=0(在后面的运算中用来存余数) __asm{ rdtsc //RDTSC指令,意思是读取时间标记计数器(Read Time-Stamp Counter) mov ecx,offset time //将time的偏移地址存入ecx mov [ecx+0],edx //把TSC的值的高32位存入[ecx+0]中 mov [ecx+4],eax //把TSC的值的低32位存入[ecx+4]中 } Sleep(1000); //延时1秒 __asm{ rdtsc mov ebx,offset time //将time的偏移地址存入ebx sub eax,[ebx+4] //把延时1秒后的TSC值的高32位减去1秒前的TSC值的高32位 sbb edx,[ebx+0] //把延时1秒后的TSC值的低32位减去1秒前的TSC值的低32位 mov ecx,1000000000 div ecx //将2次TSC差值除以1,000,000,000 mov a,eax //将结果中的商赋值于a mov b,edx //将结果中的余数赋值于b } b=b/10000000; //取余数中的最高2位 printf("该机CPU主频是: %d.%dGHz\n",a,b); //打印结果 return a*1000+b*10; } int main() { size = getCPUFrequency()*2/5*1000000;// 解释第一点 size -= 100000;//解释第二点 while(1) { for(int i=0; i < size; i++) ; Sleep(10);//解释第三点 } return 0; }
next: mov eax, dword ptr[i]; 将i 的值放入寄存器 add eax, 1; 寄存器加1 mov dword ptr[i], eax; 寄存器赋值回i cmp eax, dword ptr[n]; 比较i 和 n jl next; 小于n 则继续执行
解释第三点:至于CPU的睡眠时间,10ms 是接近windows的调度时间片。
现在的电脑很难看到单核的CPU了所以在程序的运行过程中在windows的任务管理器中的进程模块中找到程序的运行号,点击鼠标右键,设置相关性,将此运行的程序用一个CPU核心来运行
原文地址:http://blog.csdn.net/china_zoujinyong/article/details/25336277