我目前正在使用 C++ 在 Windows 中编写一个应用程序,我想模拟 CPU 负载。
我有以下代码:
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){}
}
我使用与此线程中给出的答案相同的方法编写了此代码:模拟稳定的 CPU 负载和峰值 https://stackoverflow.com/questions/2514544/simulate-steady-cpu-load-and-spikes
我的问题是:
- 我是否已将另一篇文章中的 C# 代码正确翻译为 C++?
- 此代码会在四核处理器上产生 50% 的平均 CPU 负载吗?
- 如何在合理的精度内找出 CPU 的负载百分比? (任务管理器是我唯一的选择吗?)
EDIT:我问这个问题的原因是我希望最终能够在合理的容差范围内生成 10,20,30,...,90% 的 CPU 负载。此代码似乎可以很好地生成 70%
有人知道我如何生成所述负载但仍然能够在不同的计算机(即具有不同的 CPU)上使用我的程序吗?
乍一看,这看起来像不漂亮但正确的 C++ 或 C(一个简单的方法是编译它)。包含缺失(<windows.h>
, <process.h>
, and <time.h>
)但除此之外它编译得很好。
注意clock
and Sleep
不是非常准确,并且Sleep
也不是很可靠。平均而言,线程函数应该按预期工作(给予或采取百分之几的变化)。
但是,关于问题 2) 你应该替换最后一个while(1){}
用一些阻挡而不是旋转的东西(例如WaitForSingleObject
or Sleep
如果你愿意的话)。否则整个程序将not四核上有 50% 的负载。由于主线程,您将在一个核心上获得 100% 的负载,再加上四个工作人员的 4x 50% 负载。显然,每个核心的总消耗量将超过 50%(并且会导致线程从一个核心跳到另一个核心,从而产生令人讨厌的副作用)。
使用任务管理器或类似的实用程序来验证是否获得了所需的负载是一个不错的选择(并且因为它是easiest解决方案,这也是最好的解决方案)。
另请注意,以这种方式模拟负载将probably种工作,但不是 100% 可靠。
可能存在难以预测的影响(内存、执行单元)。例如,假设您在此循环中使用了 100% 的 CPU 整数执行单元(合理的假设),但浮点或 SSE 单元为零。现代 CPU 可能会在实际核心或逻辑核心之间共享资源,您可能无法准确预测会得到什么效果。或者,另一个线程可能受内存限制或存在严重页面错误,因此减少 CPU 时间不会像您想象的那样影响它(实际上可能会给它足够的时间来使预取更好地工作)。或者,它可能会阻止 AGP 传输。或者,还有其他你不能说的事情。
EDIT:
改进的版本,更短的代码,修复了一些问题并且也按预期工作:
- Uses
clock_t
对于返回的值clock
(这在技术上比使用非专门的“更正确”typedef
'd 整数。顺便说一句,这可能就是原始代码无法按预期工作的原因,因为clock_t
is a signedWin32 下的整数。条件在if()
总是评价true
,所以worker几乎一直在睡觉,不消耗CPU。
- 旋转时代码更少,数学更简单。计算未来 50 个时钟周期的唤醒时间并旋转直至达到该时间。
- 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.
- 与原始代码一样,这假设
clock
and Sleep
使用相同的刻度线。这无疑是一个大胆的假设,但在您在原始代码中使用的 Win32 下它是正确的(两个“刻度”都是毫秒)。 C++没有类似的东西Sleep
(没有boost::thread
,或 C++11std::thread
),因此,如果打算实现非 Windows 可移植性,无论如何您都必须重新考虑。
- 与原始代码一样,它依赖于函数(
clock
and Sleep
),这是不精确且不可靠的。Sleep(50)
equals Sleep(63)
在我的系统上不使用timeBeginPeriod
。尽管如此,该程序运行得“几乎完美”,导致我的机器负载增加了 50% +/- 0.5%。
-
与原始代码一样,这没有考虑线程优先级。具有高于正常优先级的进程将完全不受此限制代码的影响,因为这就是 Windows 调度程序的工作原理 http://msdn.microsoft.com/en-us/library/windows/desktop/ms685100%28v=vs.85%29.aspx.
#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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)