让CPU占用率曲线听你指挥---linux

来源:转载

编程之美上的第一题,任务管理器上显示的使用率是这样计算的,在其刷新周期内实际执行的指令的条数/总共可以执行的条数。总的执行条数,可以通过主频算得,还要考虑超流水;实际执行条数就难算了。又注意到,CPU在执行运算时是全速进行的,所以可以让CPU在一小段时间内全速执行,一小段时间里什么也不干。

另外,多核CPU会发生进程在CPU之间的切换,不过各种操作系统都有设置进程CPU亲和度的系统调用,linux系统是sched_setaffinity。

下面这个程序可以运行在双核以上电脑上,你会看到一个CPU在画直线,另一个在画sin曲线。很好玩吧!

#include <stdio.h>
#include <math.h>

#include <unistd.h>
#include <sys/times.h>
#define __USE_GNU
#include <sched.h>


// 设置进程在哪个cpu上运行
void set_cpu(int id)
{
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(id, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1) {
fprintf(stderr, "warning: could not set CPU affinity/n");
}
}

clock_t Hz; // 时钟中断频率

void draw_line(int cpu_id)
{
set_cpu(cpu_id);

clock_t busy = Hz / 50; // 20ms
clock_t idle = busy;
clock_t start;
while (1) {
start = times(NULL);
// busy loop
while (times(NULL) - start <= busy)
;

// idle loop
usleep(idle * 1000 * 1000 / Hz);
}
}

#define COUNT 200 // 分成200个小区间
void draw_sin(int cpu_id)
{
set_cpu(cpu_id);

int i;
const double PI = 3.1415926;
const clock_t INTERVAL = Hz * 2;
clock_t busy_span[COUNT];
clock_t idle_span[COUNT];

clock_t half = INTERVAL / 2;
double radian = 0.0;
for (i=0; i < COUNT; ++i) { // 预计算
busy_span[i] = half * (1 + sin(PI * radian));
idle_span[i] = INTERVAL - busy_span[i];
radian += (2 / COUNT);
}

clock_t start;
for (i = 0; 1; ++i) {
i %= COUNT;
start = times(NULL);
while (times(NULL) - start <= busy_span[i])
;
usleep(idle_span[i] * 1000 * 1000 / Hz);
}
}

int main()
{
Hz = sysconf(_SC_CLK_TCK);

pid_t pid;
pid = fork();
if (pid == 0) {
draw_line(0);
} else {
draw_sin(1);
}
return 0;
}

执行的效果:


分享给朋友:
您可能感兴趣的文章:
随机阅读: