gpt4 book ai didi

c++ - 在 C++ 中模拟 CPU 负载

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:24:14 25 4
gpt4 key购买 nike

我目前正在使用 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){}
}

我使用与此线程中给出的答案相同的方法编写此代码:Simulate steady CPU load and spikes

我的问题是:

  1. 我是否已将其他帖子中的 C# 代码正确地转换为 C++?
  2. 此代码会在四核处理器上产生 50% 的平均 CPU 负载吗?
  3. 如何在合理的准确度内找出 CPU 的负载百分比? (任务管理器是我唯一的选择吗?)

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

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

最佳答案

乍一看,这看起来像不完美但正确的 C++ 或 C(确定的一种简单方法是编译它)。缺少包含( <windows.h><process.h><time.h> ),但编译正常。

请注意 clockSleep不是非常准确,并且Sleep也不是很可靠。不过,平均而言,线程函数应该按预期工作(给出或接受几个百分比的变化)。

但是,关于问题 2),您应该替换最后一个 while(1){}用阻塞而不是旋转的东西(例如 WaitForSingleObjectSleep 如果你愿意的话)。否则整个程序将不会在四核上有 50% 的负载。由于主线程,您将在一个核心上拥有 100% 的负载,加上来自您的四个工作线程的 4x 50%。这显然会导致每个核心超过 50%(并且会导致线程从一个核心反弹到另一个核心,从而导致严重的副作用)。

使用任务管理器或类似的实用程序来验证您是否获得了所需的负载是一个不错的选择(因为它是最简单的解决方案,所以它也是最好的解决方案)。

另请注意,以这种方式模拟负载可能会起作用,但并非 100% 可靠。
可能存在难以预测的影响(内存、执行单元)。例如,假设您在此循环中使用了 100% 的 CPU 整数执行单元(合理的假设),但它的 float 或 SSE 单元为零。现代 CPU 可能会在实核或逻辑核之间共享资源,您可能无法准确预测得到的效果。或者,另一个线程可能受内存限制或有严重的页面错误,因此占用 CPU 时间不会像您想象的那样影响它(实际上可能会给它足够的时间来使预取更好地工作)。或者,它可能会阻止 AGP 传输。或者,您无法分辨的其他内容。

编辑:

改进后的版本,更短的代码修复了一些问题并且也能按预期工作:

  • 使用 clock_t clock 返回的值(从技术上讲,这比使用不是特别使用 typedef 的整数“更正确”。顺便说一句,这可能就是原始代码无法按预期工作的原因,因为 clock_t 是一个已签名 Win32 下的整数。if() 中的条件总是计算true ,所以工作人员几乎一直在 sleep ,不消耗 CPU。
  • 旋转时代码更少,数学运算更简单。计算 future 50 个滴答的唤醒时间并旋转直到到达该时间。
  • 使用 getchar最后阻止程序。这不会消耗 CPU 时间,并且允许您通过按 Enter 结束程序。线程没有像通常那样正确结束,但在这种简单的情况下,让操作系统在进程退出时终止它们可能没问题。
  • 与原始代码一样,这里假设 clockSleep使用相同的滴答声。诚然,这是一个大胆的假设,但它在您在原始代码中使用的 Win32 下是正确的(两个“刻度”都是毫秒)。 C++ 没有类似 Sleep 的东西(没有 boost::thread 或 C++11 std::thread ),因此如果想要非 Windows 可移植性,您无论如何都必须重新考虑。
  • 与原始代码一样,它依赖于不精确且不可靠的函数(clockSleep)。 Sleep(50)等于 Sleep(63)在我的系统上不使用 timeBeginPeriod .尽管如此,该程序“几乎完美”地工作,导致我的机器上有 50% +/- 0.5% 的负载。
  • 与原始代码一样,这没有考虑线程优先级。具有高于正常优先级的进程将完全不受此限制代码的影响,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++ - 在 C++ 中模拟 CPU 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14231322/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com