首页 > 代码库 > 玩转CPU之直线
玩转CPU之直线
最近在看编程之美,看到第一个问题时,一下子就被吸引了,原来在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; }
现在来解释第一点:现代CPU每个时钟周期可以执行两条以上的代码,取平均值就是2。CPU的主频表示1秒执行加法的次数,对于除以5的运算,因为在底层的加法实现中,CPU要进行5次运算才可以进行一次加法运算。
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只执行当前这一个程序。而实际中CPU还会花时间运行其他的程序,所以在运行这个程序时需要将运行的次数适当的减少,至于减少的数量依当前OS的运行进程而定。
解释第三点:至于CPU的睡眠时间,10ms 是接近windows的调度时间片。
现在的电脑很难看到单核的CPU了所以在程序的运行过程中在windows的任务管理器中的进程模块中找到程序的运行号,点击鼠标右键,设置相关性,将此运行的程序用一个CPU核心来运行
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。