近期在看編程之美,看到第一個問題時,一會兒就被吸引了,原來在windows 的任務管理器中還可以讓CPU舞動起來,再一次的相信了編程中僅僅有想不到沒有作不到,對於書中的作法和網上的實現大體都一樣。只是在看後面的解法以前,個人解法和書中第一種簡單的控制之法一樣,而且我還引入了一個實時監測CPU主頻的函數。可以移植到其它的PC上。ios
#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核心來執行windows