CPU使用率不稳定

时间:2015-06-08 09:02:13

标签: c cpu-usage

我目前正在用C语言编写应用程序,我打算在ubuntu中模拟CPU负载小于100%。我使用阶乘算法强调我的CPU和nanosleep函数来调节CPU使用率。目标是稳定的CPU使用率和合理的容差,可以逐步变化,即20%,30%等。问题是,当我启动我的应用程序时,我得到弹跳负载45-53%,我希望加载50%的CPU使用率。由于我的研究,我需要获得稳定的CPU使用率,我通过跟踪两次执行之间的时间戳来计算响应时间。

编辑我正在使用VmWare Workstation和Ubuntu 14.04 VM进行研究。 这是代码

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

int main(void)
{
    struct timeval t1;

    int milisec = 5; // length of time to sleep, in miliseconds
    struct timespec req = {0};
    req.tv_sec = 0;
    req.tv_nsec = milisec * 1000000L;

    FILE *file; 
    file = fopen("trace.txt", "w");
    //int j = 0;
    while(1)
    {
        gettimeofday(&t1, NULL);        
        int i;
        int res = 1;
        for(i = 0; i < 580000; i++)
        {   
            res = res*i;    
        }



        nanosleep(&req, (struct timespec *)NULL);


        fprintf(file, "%llu%llu\n", (unsigned long long)t1.tv_sec, (unsigned long long)t1.tv_usec);
        fflush(file);
        //j++;
    }
}

1 个答案:

答案 0 :(得分:2)

这是我对它的看法 - 在我的光测试中看起来相当不错。基本的想法是使用getrusage跟踪程序的CPU时间,除以挂钟经过的时间,如果超过目标比率则收益。您可以看到它是否提供比您自己的代码更稳定的结果。

(注意:问题是标记为C ++而不是C最初...代码可以简单地移植到C)

#include <iostream>
#include <sstream>
#include <sys/time.h>
#include <sys/resource.h>

void usage_exit(const char* argv0)
{
    std::cerr << "usage " << argv0 << " <target>\n"
        "   spin burning <target> proportion of one CPU (e.g. 0.5 = 50%)\n";
    exit(1);
}

int main(int argc, const char* argv[])
{
    if (argc != 2)
        usage_exit(argv[0]);
    std::istringstream iss(argv[1]);
    double target;
    if (!(iss >> target))
        usage_exit(argv[0]);

    struct timeval start, now;
    gettimeofday(&start, 0);

    struct rusage usage;
    while (getrusage(RUSAGE_SELF, &usage) == 0)
    {
        gettimeofday(&now, 0);
        double running = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1E-6 +
                         usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1E-6;
        double elapsed = now.tv_sec - start.tv_sec +
                         now.tv_usec * 1E-6 - start.tv_usec * 1E-6;
        if (running / elapsed > target)
            pthread_yield();
    }
}