51Testing软件测试论坛

标题: 请教高手:处理器余量测试问题 [打印本页]

作者: alexliu@CETC    时间: 2010-8-11 22:53
标题: 请教高手:处理器余量测试问题
1)Vxworks下,除了spy函数外,还有什么比较好的方法?网上有些文章说创建一个优先级最低的任务,给出的源代码有问题,且没把原理讲清楚。
2)DSP软件,是否有处理器余量的概念?如果有,如何测试?

请高手指点一二,小弟先谢了!
作者: eric_woo    时间: 2010-8-13 20:27
标题: 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计算资源使用情况。




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2