Linux下操纵CPU曲线绘制心形

标签: linux cpu 曲线 | 发表时间:2011-08-03 00:16 | 作者:王小兵 TheLover_Z
出处:http://www.cnblogs.com/

不久之前看了「编程之美」,里面有在windows下操纵CPU绘制正弦曲线的示例程序。思路很简单,但是需要知道几个windowsAPI函数。

刚开始我想尝试在windows下绘制心形,不过没能做到,原因是CPU曲线是CPU利用率和时间构成的函数的关系,心形是一个封闭图形,不可能是一个函数,所以至少需要两条CPU曲线才能绘制(这需要你的机器为双核或多核或者多个CPU),然而windows的任务管理器,我没能找到将两条CPU曲线绘制在同一图表下的方法,所以没能成功。

不过ubuntu下的任务管理器可以,而且还可以设置CPU曲线的颜色。以下是我在ubuntu下任务管理器的截图,我把两条CPU曲线都设置成了红色,设置CPU曲线的刷新速率为2s

  绘制正弦曲线的程序思路很简单,在看过「编程之美」后,完全可以仿照写出Linux版本,只是引用的库和调用的API函数不通而已。书中没有双核的参考程序,要让特定的线程在特定的cpu上运行需要设置cpu亲和度,windows下可参考这篇博客http://blog.csdn.net/wesweeky/article/details/6402564

我本来想用经典的心形曲线X^2+(y-(x^2)^(1/3))^2=1来绘制,但是效果不是很好,所以干脆使用几个分段的二次函数。详细代码如下:

/*Programmed by Wang Zaijing 2011-08-01*/
#include
<stdio.h>
#include
<pthread.h>
#include
<unistd.h>

#include
<stdlib.h>
#include
<math.h>
#include
<time.h>
#include
<sys/time.h>

#define SAMPLE_COUNT 800 //设置800个抽样点
#define INCREAMENT 0.0025 //增量为0.0025=2/800
#define SAMPLE_TIME 25 //设置每个抽样点的时间片


double GetSysTime() //Windows中直接使用GetTickSAMPLE_COUNT()函数./ms
{
struct timeval tv;
gettimeofday(
&tv, NULL);
return (tv.tv_sec*1000+tv.tv_usec*1.0/1000);
}

int GetCpuNums()
{
return (int)sysconf(_SC_NPROCESSORS_ONLN);
}

  

thread_cpu1()
void *thread_cpu1(void*arg)          //线程函数1
{
double busy_cache[SAMPLE_COUNT]; //CPU占用时间,缓存一个周期的计算结果
double idle_cache[SAMPLE_COUNT]; //CPU空闲时间

double radian = 0.0; //增量从0开始,最大值到2=SAMPLE_COUNT*INCREAMENT

double start_time; //开始时间

double temp;
//一个周期内为分段函数分为四段
for(int i=0; i<SAMPLE_COUNT/4; i++)
{
temp
= (double)(-8.0*(radian-0.25)*(radian-0.25)+1);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i=SAMPLE_COUNT/4; i<SAMPLE_COUNT/2; i++)
{
temp
= (double)(-8.0*(radian-0.75)*(radian-0.75)+1);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i= SAMPLE_COUNT/2; i < 3*SAMPLE_COUNT/4; i++)
{
temp
= (double)(0.667*(radian-2)*(radian-2)-0.167);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i= 3*SAMPLE_COUNT/4; i < SAMPLE_COUNT; i++)
{
temp
= (double)(0.667*(radian-1)*(radian-1)-0.167);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i = 0; ; i = (i + 1) % SAMPLE_COUNT)
{
start_time
= GetSysTime();
while((GetSysTime()-start_time) <= busy_cache[i]);
usleep(idle_cache[i]
*1000);
}
return NULL;
}

  

thread_cpu2()
void *thread_cpu2(void*arg)//线程函数2,原理同线程函数1
{
double busy_cache[SAMPLE_COUNT];
double idle_cache[SAMPLE_COUNT];

double radian = 0.0;

double start_time;


double temp;


for(int i=0; i<SAMPLE_COUNT/4; i++)
{

temp
= (double)(0.667*(radian-1)*(radian-1)-0.167);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i= SAMPLE_COUNT/4; i < SAMPLE_COUNT/2; i++)
{
temp
= (double)(0.667*(radian)*(radian)-0.167);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i=SAMPLE_COUNT/2; i<3*SAMPLE_COUNT/4; i++)
{
temp
= (double)(-8.0*(radian-1.25)*(radian-1.25)+1);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i=3*SAMPLE_COUNT/4; i<SAMPLE_COUNT; i++)
{
temp
= (double)(-8.0*(radian-1.75)*(radian-1.75)+1);
busy_cache[i]
= (double)(SAMPLE_TIME*temp);
idle_cache[i]
= (double)(SAMPLE_TIME - busy_cache[i]);
radian
+= INCREAMENT;
}

for(int i = 0; ; i = (i + 1) % SAMPLE_COUNT)
{
start_time
= GetSysTime();
while((GetSysTime()-start_time) <= busy_cache[i]);
usleep(idle_cache[i]
*1000);
}
return NULL;
}

  

int main()//主函数
{
//int cpu_num = 0;
//cpu_num = GetCpuNums();
//printf("The number of cpu is %d\n", cpu_num);

pthread_t t1;
pthread_t t2;
pthread_attr_t attr1;
pthread_attr_t attr2;

pthread_attr_init(
&attr1);
pthread_attr_init(
&attr2);

if (0!=pthread_create(&t1, &attr1, thread_cpu1, NULL))//创建线程1
{
printf(
"error:Create thread 1\n");
return 0;
}

if (0!=pthread_create(&t2, &attr2, thread_cpu2, NULL))//创建线程2
{
printf(
"error:Create thread 2\n");
return 0;
}

cpu_set_t cpu_info;
CPU_ZERO(
&cpu_info);
CPU_SET(
0, &cpu_info);
if (0!=pthread_setaffinity_np(t1, sizeof(cpu_set_t), &cpu_info))
{
printf(
"error:Thread 1 set affinity failed.\n");
}

CPU_ZERO(
&cpu_info);
CPU_SET(
1, &cpu_info);
if (0!=pthread_setaffinity_np(t2, sizeof(cpu_set_t), &cpu_info))
{
printf(
"error:Thread 2 set affinity failed.\n");
}

pthread_join(t1, NULL);
//释放线程t1
pthread_join(t2, NULL);//释放线程t2
return 0;
}

  

总结几点:

1.   Linux下的cpu亲和度

CPU 亲和性(affinity 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为  CPU 亲和性(affinity 的特性,这意味着进程通常不会在处理器之间频繁迁移,windows则不然,如果你的电脑是双核,你会看到两条cpu曲线近似相同,进程几乎被两个cpu均分。

Linux下的cpu亲和度可以参考以下博文,讲的非常清楚

http://www.ibm.com/developerworks/cn/linux/l-affinity.html

2.   终端编译出错:undefined reference to'pthread_reate' 加上-lpthread 如:gcc test.c –lpthread 。若使用IDE Code::Blocks 编译出错则要进行以下设置:

Project -> Build options -> Linker settings -> Link libraries 里加上pthread

3   Happy Birthday to「某*.    This is just for you.

 

【参考文献】《编程之美》

【参考博客】管理处理器的亲和性 http://www.ibm.com/developerworks/cn/linux/l-affinity.html

【参考博客】让CPU占用率曲线听你指挥http://blog.csdn.net/wesweeky/article/details/6402564

【参考博客】Linuxpthread的线程亲和性研究http://blog.sina.com.cn/s/blog_6a1837e90100nrlj.html

作者: 王小兵 发表于 2011-08-03 00:16 原文链接

评论: 3 查看评论 发表评论


最新新闻:
· 社交网络身份管理服务商Janrain融资1550万美元(2011-08-03 15:43)
· 淘宝网出现系统故障 付费卖家页面被清空(2011-08-03 15:17)
· 京东卓越等截留用户网购退款:提现需提申请(2011-08-03 15:13)
· 淘宝数据魔方技术架构解析(2011-08-03 15:12)
· 奇艺3000万资源推广新《水浒》 视链技术贯穿全剧(2011-08-03 15:10)

编辑推荐:谷歌是如何做代码审查的

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [linux cpu 曲线] 推荐:

Linux下操纵CPU曲线绘制心形

- TheLover_Z - 博客园-首页原创精华区
不久之前看了「编程之美」,里面有在windows下操纵CPU绘制正弦曲线的示例程序. 思路很简单,但是需要知道几个windows的API函数. 刚开始我想尝试在windows下绘制心形,不过没能做到,原因是CPU曲线是CPU利用率和时间构成的函数的关系,心形是一个封闭图形,不可能是一个函数,所以至少需要两条CPU曲线才能绘制(这需要你的机器为双核或多核或者多个CPU),然而windows的任务管理器,我没能找到将两条CPU曲线绘制在同一图表下的方法,所以没能成功.

动态切换 Linux 使用的 CPU 数量

- 李帅 - Wow! Ubuntu
由于要测试一些代码,其运行结果会受到多核并行的影响,所以希望能够调整使用的 CPU 数量. 网络上之前看到的方法是在内核的启动参数上添加一个 maxcpus,但是如果这样的话每切换一次都要重启一次,是在太麻烦了. 想想 Linux 应该是很强大的,所以可以动态修改 CPU 数量才对. 无意中看到 Linux 代码的 Documentation 文件夹下有个文件叫做 cpu-hotplug.txt,于是就看了一下,发现可以在 /sys/devices/system/cpu 看到代表各 CPU 的文件夹按照 cpuX 的命名方式,如 cpu0、cpu1、cpu2 等.

Linux中模拟诊断Oracle高CPU占用

- - CSDN博客推荐文章
1,在一个session中模拟CPU高使用率,如下:. 2,在shell窗口用top命令查看CPU使用情况:                                                                                                            .

Linux中常用的监控CPU整体性能的工具

- - CSDN博客编程语言推荐文章
Linux中常用的监控CPU整体性能的工具有:. top:命令是一个优秀的交互式实用工具,用于监视性能. 它提供关于整体Linux性能的几个概要行,但是报告进程信息才是top真正的长处. 可以广泛自定义进程显示,也可以添加字段,按照不同指标排序进程列表,甚至从top注销进程. 显示的信息同ps接近,但是top可以了解到CPU消耗,可以根据用户指定的时间来更新显示.

Linux HotSopt虚拟机GC线程的CPU占用率

- - ImportNew
下面的问题将会检验你有关Linux系统上的Java程序的垃圾回收和High CPU排错的知识. 在过度调用GC或及CPU占用率过高的时候,这种排错技术是至关重要的. 假设你没有使用像是 Compuware dynaTrace或者JVisualVMware这样先进的监视工具. 有关于这些工具的使用教程将会在以后发布,但是请先确保自己掌握了基础的排错原则.

Linux下java进程CPU占用率高-分析方法

- - Linux - 操作系统 - ITeye博客
今天登陆同事的一台gateway 开始以为hive环境登陆不了了,仔细一看看了下是因为机器很卡,我每次等几秒没登陆就ctrl+c了,看了下是有个java进程cpu:340.4%  mem:14.6%. 一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用.

Linux下如何查看高CPU占用率线程

- - C++博客-首页原创精华区
在 Linux 下 top 工具可以显示 cpu 的平均利用率(user,nice,system,idle,iowait,irq,softirq,etc.),可以显示每个 cpu 的利用率. 但是无法显示每个线程的 cpu 利用率情况,. 这时就可能出现这种情况,总的 cpu 利用率中 user 或 system 很高,但是用进程的 cpu 占用率进行排序时,没有进程的 user 或 system 与之对应.

java问题导致linux负载、cpu过高如何定位

- - CSDN博客推荐文章
1.用top找到最耗资源的进程id. 2.查询最消耗资源的java进程. 3.打印java 栈 信息. 4.将耗资源的javaPID转换为16进制(5920转1720<16进制>  去百度找 :十进制转十六进制). PID 对应 堆栈中的nid(16进制). 去stack.txt 中查找nid=1720的问题.

(转)简单的 Linux下的CPU性能瓶颈分析

- - jackyrong
Linux下的CPU性能瓶颈分析. 以夕 发表于:2013-09-29 浏览:2455次 评论:0次 所属分类: 性能测试.         在对notify执行性能测试时发现cpu负载突然飙高,cpu利用率高达95%. 这时候就要排查是哪些线程消耗了cpu,并从代码层找到占用cpu的“罪魁祸首”.

8086 CPU 寄存器简介

- 田野 - 博客园-首页原创精华区
打算写几篇稍近底层或者说是基础的博文,浅要介绍或者说是回顾一些基础知识,. 自然,还是得从最基础的开始,那就从汇编语言开刀吧,. 从汇编语言开刀的话,我们必须还先要了解一些其他东西,. 像  CPU ,内存这些知识点还是理解深刻一点的比较好,. 所以这一篇博文就绕着 80x86  CPU 中寄存器的基础部分下手,至于其他的一些将会在后续的博文中介绍.