在C ++中模拟CPU负载 [英] Simulating CPU Load In C++
问题描述
我目前正在使用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
我的问题是:
- 我是否已将另一篇文章中的C#代码正确转换为C ++?
- 此代码是否会在Windows上平均产生50%的CPU负载四核处理器?
- 如何在合理的精度范围内找出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:
- 使用
clock_t
表示clock
返回的值(从技术上讲,它比使用非专门的typedef
返回的值更正确偶然地,这可能就是原始代码无法按预期工作的原因,因为clock_t
是Win32下的 signed 整数。if()
中的值始终为true
,因此工作人员几乎所有时间都在睡觉,不占用CPU。 - 更少的代码,旋转时数学不那么复杂。计算将来的唤醒时间50滴答,然后旋转直到达到该时间。
- 使用
getchar
最终阻止程序,这不会消耗CPU时间,它允许您通过按 Enter 来结束程序。可以正常结束,但是在这种简单的情况下,可以让OS在进程退出时终止它们。 - 与原始代码类似,假定
时钟
和睡眠
使用相同的刻度。诚然,这是一个大胆的假设,但在您在原始代码中使用的Win32下,它仍然适用(两个滴答都是毫秒)。 C ++没有类似Sleep
的东西(没有boost :: thread
或C ++ 11std :: thread
),因此,如果要实现非Windows的可移植性,则无论如何都要重新考虑。 - 就像原始代码一样,它依赖功能(
时钟
和睡眠
)不精确且不可靠。Sleep(50)
等于我系统上的Sleep(63)
,而无需使用timeBeginPeriod
。尽管如此,该程序仍能几乎完美地运行,从而在我的机器上造成50%+/- 0.5%的负载。 -
与原始代码一样,它没有线程优先级考虑在内。此限制代码因为这是Windows计划程序的工作方式。
- Uses
clock_t
for the value returned byclock
(which is technically "more correct" than using a not speciallytypedef
'd integer. Incidentially, that's probably the very reason why the original code does not work as intended, sinceclock_t
is a signed integer under Win32. The condition inif()
always evaluatestrue
, 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
andSleep
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 likeSleep
(withoutboost::thread
, or C++11std::thread
), so if non-Windows portability is intended, you'd have to rethink anyway. - Like the original code, it relies on functions (
clock
andSleep
) which are unprecise and unreliable.Sleep(50)
equalsSleep(63)
on my system without usingtimeBeginPeriod
. 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屋!