首页 > 其他 > 详细

读编程之美1.1——让CPU占用率曲线听你的指挥

时间:2014-03-03 16:31:59      阅读:529      评论:0      收藏:0      [点我收藏+]

这是个有趣的问题,可以作为学习Windows编程的入门程序。我不懂Windows编程。单是看见那些微软自定义的类型就畏惧,全是大写,还有他们定义的各种错误代码,真是记不住,不过这些丝毫不会影响解决这个问题。《编程之美》讲解的是问题的解决思路与解决方案,不会过多的叙述繁杂的函数使用规范,因此读起来不枯燥。希望借这次开博客的机会能督促自己解完上面的题目。

书中给出的解决方案都是针对一个核的CPU,讨论部分提到了多核,并诱导了读者如何去解决多核的情况。

书中提到两个重要的API,GetProcessorInfo()与SetThreadAffinityMask()。经查询MSDN,GetProcessorInfo()是Windows Server上的API,在PC机上不好用,所以可以尝试GetSystemInfo()来获得核数。实际上在Windows平台上直接用任务管理器(图1)就可以查看,比如我的笔记本CPU型号是Intel(R) Core(TM) i5-3210M CPU @2.5GHz,有四个核,任务管理器上会用四个窗口来显示CPU的使用情况(Windows7)。

一般情况下,一个线程使用哪个核应该取决于任务调度程序,会不时的切换,不会固定在一个核上,可以用下面的一段程序简单测试:

bubuko.com,布布扣
#include <cstdio>
#include <windows.h>

int main()
{
    while(true) {
        int nNum = (int)GetCurrentProcessorNumber();
        printf("%d\n", nNum);
        Sleep(1000);
    }
    return 0;
}
bubuko.com,布布扣

输出情况是0,1,2等数字没有规律的切换出现。若想指定某一个核执行某个任务,就需要将对应的任务(线程)分派给某一个核,分派的函数也就是SetThreadAffinityMask()。这个函数的参数有两个,第一个是执行任务的句柄,第二个是核的掩蔽码。掩蔽码的使用规则是如果最低位置1,就将任务分派给编号为0的核,如果次低位置1,就将任务分派给编号为1的核。据此来看,如果掩蔽码设置为0xC,即编号为2, 3的核被置为1,线程就会在这两个核上切换。清楚了这个,让四个核画正弦曲线(图1)也就容易了。可以参考下面的代码:

bubuko.com,布布扣
#include<windows.h>
#include<cstdio>
#include<cmath>

// 让多个核一起绘制正弦曲线

const int SAMPLING_COUNT = 200; // 抽样点数
const double PI = 3.1415926535; // 圆周率
const int TOTAL_AMPLITUDE = 100; // 采样的时间片, 算来一个周期是20s

DWORD dwBusySpan[SAMPLING_COUNT];

void showSine(void *para)
{
    for(int i = 0; ; i = (i+1) % SAMPLING_COUNT) {
        DWORD dwStartTime = GetTickCount();
        while(GetTickCount() - dwStartTime <= dwBusySpan[i])
            ;
        Sleep(TOTAL_AMPLITUDE - dwBusySpan[i]);
    }
}

int main()
{
    // 计算忙的时间
    int nAmplitude = TOTAL_AMPLITUDE / 2;
    double lfRadian = 0.0;
    double lfRadianIncrement = 2.0 / SAMPLING_COUNT;
    for(int i = 0; i < SAMPLING_COUNT; ++i) {
        dwBusySpan[i] = (DWORD)(nAmplitude + nAmplitude * sin(PI * lfRadian));
        lfRadian += lfRadianIncrement;
    }

    SYSTEM_INFO info;
    GetSystemInfo(&info);
    int nNum = info.dwNumberOfProcessors;

    DWORD dwThreadId;
    HANDLE hThread;
    for(int i = 0; i < nNum; ++i) {
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)showSine, NULL, 0, &dwThreadId);
        SetThreadAffinityMask(hThread, (1<<i));
    }

    WaitForSingleObject(hThread, INFINITE);
    return 0;
}
bubuko.com,布布扣

bubuko.com,布布扣

图1 任务管理器

读编程之美1.1——让CPU占用率曲线听你的指挥,布布扣,bubuko.com

读编程之美1.1——让CPU占用率曲线听你的指挥

原文:http://www.cnblogs.com/foreverinside/p/3577273.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!