在C ++中模拟CPU负载 [英] Simulating CPU Load In C++

查看:120
本文介绍了在C ++中模拟CPU负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用C ++在Windows中编写应用程序,我想模拟CPU负载。

I am currently writing an application in Windows using C++ and I would like to simulate CPU load.

我有以下代码:

void task1(void *param) { 

unsigned elapsed =0;
unsigned t0;

while(1){

    if ((t0=clock())>=50+elapsed){//if time elapsed is 50ms

        elapsed=t0;
        Sleep(50);
    }
  }
}

int main(){

int ThreadNr;

for(int i=0; i < 4;i++){//for each core (i.e. 4 cores)
    _beginthread( task1, 0, &ThreadNr );//create a new thread and run the "task1" function
}

while(1){}
}

我使用与该线程给出的答案相同的方法编写了这段代码:

I wrote this code using the same methodology as in the answers given in this thread: Simulate steady CPU load and spikes

我的问题是:


  1. 我是否已将另一篇文章中的C#代码正确转换为C ++?

  2. 此代码是否会在Windows上平均产生50%的CPU负载四核处理器?

  3. 如何在合理的精度范围内找出CPU的负载百分比? (任务管理器是我唯一的选择吗?)

编辑:我问这个问题的原因是我希望最终能够在合理的公差范围内产生10、20、30,...,90%的CPU负载。该代码对于产生70%的负载似乎效果很好。但是在低于70%的任何负载下(由任务管理器CPU负载读数衡量)似乎都非常不准确。

The reason I ask this question is that I want to eventually be able to generate CPU loads of 10,20,30,...,90% within a reasonable tolerance. This code seems to work well for to generate loads 70%< but seems to be very inaccurate at any load below 70% (as measured by the task manager CPU load readings).

有人会对我如何生成上述负载但仍然能够在不同计算机(即具有不同CPU)上使用我的程序有任何想法吗?

Would anyone have any ideas as to how I could generate said loads but still be able to use my program on different computers (i.e. with different CPUs)?

推荐答案

乍一看,这看起来像是不正确但正确的C ++或C(确保编译的一种简便方法) 。缺少内容(< windows.h> < process.h> < time.h> ),否则可以正常编译。

At first sight, this looks like not-pretty-but-correct C++ or C (an easy way to be sure is to compile it). Includes are missing (<windows.h>, <process.h>, and <time.h>) but otherwise it compiles fine.

请注意,时钟 Sleep 并不十分准确,而 Sleep 也不十分可靠。平均而言,线程功能应该可以按预期进行工作(给予或采取一些百分比的变化)。

Note that clock and Sleep are not terribly accurate, and Sleep is not terribly reliable either. On the average, the thread function should kind of work as intended, though (give or take a few percent of variation).

但是,关于问题2),您应该替换掉最后一个 while(1){} 具有阻止而不是旋转的功能(例如 WaitForSingleObject 睡眠(如果愿意)。否则,整个程序将在四核上具有50%的负载。由于主线程,一个核心上将有100%的负载,而您的四个工作人员将有4x 50%的负载。显然,这将使每个内核的总和超过50%(并且将导致线程从一个内核反弹到另一个内核,从而导致令人讨厌的副作用)。

However, regarding question 2) you should replace the last while(1){} with something that blocks rather than spins (e.g. WaitForSingleObject or Sleep if you will). otherwise the entire program will not have 50% load on a quadcore. You will have 100% load on one core due to the main thread, plus the 4x 50% from your four workers. This will obviously sum up to more than 50% per core (and will cause threads to bounce from one core to the other, resulting in nasty side effects).

使用任务Manager或类似的工具,用于验证您是否希望获得所需的负载是一个不错的选择(并且由于它是最简单的解决方案,因此也是最好的解决方案)。

Using Task Manager or a similar utility to verify whether you get the load you want is a good option (and since it's the easiest solution, it's also the best one).

也请注意,以这种方式模拟负载可能会 种工作,但并非100%可靠。

可能会有影响(内存,执行单位)。例如,假设您在此循环中使用了100%的CPU整数执行单位(合理的假设),但其浮点数或SSE单位为零。现代CPU可能会在实际或逻辑内核之间共享资源,并且您可能无法准确预测所获得的效果。或者,另一个线程可能受内存限制或存在严重的页面错误,因此占用CPU时间不会像您认为的那样对它造成太大的影响(实际上可能会给它足够的时间来使预取工作更好)。或者,它可能会阻止AGP传输。或者,您无法分辨。

Also do note that simulating load in such a way will probably kind of work, but is not 100% reliable.
There might be effects (memory, execution units) that are hard to predict. Assume for example that you're using 100% of the CPU's integer execution units with this loop (reasonable assumption) but zero of it's floating point or SSE units. Modern CPUs may share resources between real or logical cores, and you might not be able to predict exactly what effects you get. Or, another thread may be memory bound or having significant page faults, so taking away CPU time won't affect it nearly as much as you think (might in fact give it enough time to make prefetching work better). Or, it might block on AGP transfers. Or, something else you can't tell.

编辑:

已改进版本,较短的代码可以解决一些问题,并且可以按预期工作:

Improved version, shorter code that fixes a few issues and also works as intended:

  • Uses clock_t for the value returned by clock (which is technically "more correct" than using a not specially typedef'd integer. Incidentially, that's probably the very reason why the original code does not work as intended, since clock_t is a signed integer under Win32. The condition in if() always evaluates true, so the workers sleep almost all the time, consuming no CPU.
  • Less code, less complicated math when spinning. Computes a wakeup time 50 ticks in the future and spins until that time is reached.
  • Uses getchar to block the program at the end. This does not burn CPU time, and it allows you to end the program by pressing Enter. Threads are not properly ended as one would normally do, but in this simple case it's probably OK to just let the OS terminate them as the process exits.
  • Like the original code, this assumes that clock and Sleep use the same ticks. That is admittedly a bold assumption, but it holds true under Win32 which you used in the original code (both "ticks" are milliseconds). C++ doesn't have anything like Sleep (without boost::thread, or C++11 std::thread), so if non-Windows portability is intended, you'd have to rethink anyway.
  • Like the original code, it relies on functions (clock and Sleep) which are unprecise and unreliable. Sleep(50) equals Sleep(63) on my system without using timeBeginPeriod. Nevertheless, the program works "almost perfectly", resulting in a 50% +/- 0.5% load on my machine.
  • Like the original code, this does not take thread priorities into account. A process that has a higher than normal priority class will be entirely unimpressed by this throttling code, because that is how the Windows scheduler works.

#include <windows.h>
#include <process.h>
#include <time.h>
#include <stdio.h>


void task1(void *)
{
    while(1)
    {
        clock_t wakeup = clock() + 50;
        while(clock() < wakeup) {}
        Sleep(50);
    }
}

int main(int, char**)
{
    int ThreadNr;
    for(int i=0; i < 4; i++) _beginthread( task1, 0, &ThreadNr );

    (void) getchar();
    return 0;
}


这篇关于在C ++中模拟CPU负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆