|
CPU利用率
1)Vxworks下,除了spy函数外,还有什么比较好的方法?网上有些文章说创建一个优先级最低的任务,给出的源代码有问题,且没把原理讲清楚。
2)DSP软件,是否有处理器余量的概念?如果有,如何测试?
--------------------------------------------------------------------------------------------------
针对问题1:
是在网上看到有篇介绍当前CPU整体利用率的粗略计算的代码,包括:结构体cpuUsage、函数cpuBurn()、cpuUsageTask()、getCpu()和cpuUsageInit(),不知所指是否为此段代码。此前使用过此代码,因为某个项目的中ppc板的定时器都被占用。当时也是囫囵利用,没有细致分析。昨天看到此帖,重新看看那段代码后添些注释,但愿拙见有益于仁兄。
#include "VxWorks.h"
#include "semLib.h"
#include "taskLib.h"
#define SECONDS_TO_BURN 60
typedef struct cpuUsage {
SEM_ID startSem; //该信号量用于控制采集周期
int didNotComplete; //记录最低优先级的任务的执行状态
unsigned long ticksNoContention; //记录在无任务竞争CPU资源的情况下,SECONDS_TO_BURN宏定义的时间对应的系统ticks数目,该变量数值为常量,作为基准数值使用
int nBurnNoContention; //记录在无任务竞争CPU资源的情况下,SECONDS_TO_BURN宏定义的时间内for循环执行的次数,该变量数值为常量,作为基准数值使用
unsigned long ticksNow; //记录调用getCPU时最低优先级任务经历的系统ticks数目
int nBurnNow; //记录调用getCPU时最低优先级任务在ticksNow的时间内的for循环执行次数
double usage; //记录当前的CPU利用率
} cpuUsage;
static cpuUsage *pcpuUsage=0; //用于存储当前CPU利用率计算的相关数据信息
static double cpuBurn() // 无实质意义,用于占用CPU资源
{
int i;
double result = 0.0;
for(i=0;i<5; i++) result += sqrt((double)i);
return(result);
}
static void cpuUsageTask() // 获取CPU利用率的主要部分在此实现
{
while(TRUE) {
int i;
unsigned long tickStart,tickEnd;
semTake(pcpuUsage->startSem,WAIT_FOREVER); //若未调用getCPU,则不计算
pcpuUsage->ticksNow=0; //开启新的采集周期时,设置最低优先级任务在当前采集周期内经历的系统ticks数目为0
pcpuUsage->nBurnNow=0; //开启新的采集周期时,设置最低优先级任务在当前采集周期内经历的ticksNow时间内的for循环执行次数
tickStart = tickGet(); //获取开始时的系统ticks
//在无任务竞争的情况下,执行nBurnNoContention的时间为ticksNoContention,故此处反向推导
for(i=0; i<pcpuUsage->nBurnNoContention; i++) {
cpuBurn();
pcpuUsage->ticksNow = tickGet() - tickStart; //记录当前采样周期经历的系统ticks
++pcpuUsage->nBurnNow; //记录当前采样周期内执行的for循环次数
}
tickEnd = tickGet();
pcpuUsage->didNotComplete = FALSE; //记录当前采样周期结束
pcpuUsage->ticksNow = tickEnd - tickStart;
}
}
double getCpu() //直接打印出当前采样周期的CPU利用率
{
if(pcpuUsage->didNotComplete && pcpuUsage->nBurnNow==0) {//此为特殊情况处理
pcpuUsage->usage = 0.0;
} else {
double temp;
double ticksNow,nBurnNow;
ticksNow = (double)pcpuUsage->ticksNow; //获取当前经历的系统ticks数目
nBurnNow = (double)pcpuUsage->nBurnNow; //获取当前经历的系统ticks数目对应的时间内执行的for循环次数
//此处假设优先级最低的任务获取CPU时间的机会是线性的,故而推导出完成nBurnNoContention次for循环的系统ticks
ticksNow *= (double)pcpuUsage->nBurnNoContention/nBurnNow;
//在上面语句的假设下,推导出在最低优先级任务完成nBurnNoContention次for循环时,最低优先级任务之外的任务(即当前系统中的有效任务)总共占用的系统ticks
temp = ticksNow - (double)pcpuUsage->ticksNoContention;
//此处即为CPU利用率
temp = 100.0 * temp/ticksNow;
if(temp<0.0 || temp>100.0) temp=0.0; /*handle tick overflow*/
pcpuUsage->usage = temp;
}
pcpuUsage->didNotComplete = TRUE;
semGive(pcpuUsage->startSem);//启动新的采集周期
printf("CPU usage:%f\r\n",pcpuUsage->usage);
return(pcpuUsage->usage);
}
void cpuUsageInit(void)
{
unsigned long tickStart,tickNow;
int nBurnNoContention=0;
int ticksToWait;
//获取SECONDS_TO_BURN时间对应的系统tick数目,旨在获取基准值
ticksToWait = SECONDS_TO_BURN*sysClkRateGet();
pcpuUsage = calloc(1,sizeof(cpuUsage));
tickStart = tickGet();
/*wait for a tick*/
while(tickStart==(tickNow = tickGet())) {;}
tickStart = tickNow;
//获取SECONDS_TO_BURN时间内系统tick对应的时间内执行的for循环次数,旨在获取基准值
while(TRUE) {
if((tickGet() - tickStart)>=ticksToWait) break;
cpuBurn();
nBurnNoContention++;
}
pcpuUsage->nBurnNoContention = nBurnNoContention; //初始化基准值
pcpuUsage->startSem = semBCreate (SEM_Q_FIFO,SEM_EMPTY);
pcpuUsage->ticksNoContention = ticksToWait; //初始化基准值
pcpuUsage->didNotComplete = TRUE;
taskSpawn("cpuUsageTask",255,VX_FP_TASK,1000,(FUNCPTR)cpuUsageTask,0, 0, 0, 0, 0, 0, 0, 0, 0, 0); //创建最低优先级任务
}
针对问题2:
DSP的CPU计算资源的情况还是可以获取的,可以通过仿真器查看当前的CPU计算资源使用情况。 |
|