编写程序使CPU使用率达到50%左右

Yic*_*hao 7 c++ operating-system cpu-usage

问题描述

  • 问题的目标是在Windows上编写程序以使CPU使用率保持在50%左右.
  • 在Windows上,我们可以使用任务管理器Perfmon.exe来监视CPU使用情况.
  • CPU使用百分比应该接近50%,因为操作系统中还有许多其他任务,我们只需要占用CPU的近似使用百分比.
  • CPU可以是多核处理器或单核处理器,因此有利于通用解决方案

问题的起源

最初的问题来自编程美的第1.1章

关于这个问题的个人努力

环境

  • 处理器:Intel i5-3470,4核,4线程
  • 系统:Windows 7
  • 开发环境:Visual Studio 2010,提升库

第一次尝试

我的第一次尝试没有考虑多核和多线程,所以它不起作用,但它提供了这样的想法:如果我们希望处理器加载一半,我们可以创建一个无限循环,它占用一半的时间,并占用处理器另一半.

我将跳过第一次尝试的细节.

第二次尝试

在我的第二次努力中,情况进展顺利,但仍有一些困扰我的问题.

我的第一个解决方

以下片段是第一个可能的解决方案.它使用GetTickCount()Windows API,并使用两个线程将处理器加载到50%.

解决方案一个要点.

#include <boost/thread.hpp>
#include "windows.h"
#define INTERVAL 10

void infiniteLoop() {
    while (1) {
        DWORD startTime = GetTickCount();
        while (GetTickCount() - startTime <= INTERVAL)
            ; 
        boost::posix_time::millisec sleepTime(INTERVAL);
        boost::this_thread::sleep(sleepTime);
    }
}

int main() {
    boost::thread thread1(infiniteLoop);
    boost::thread thread2(infiniteLoop);
    thread1.join();
    thread2.join();
    char c;
    std::cin >> c;
}
Run Code Online (Sandbox Code Playgroud)

解决方案是成功的,但我不太明白为什么我只能使用两个线程来获得CPU半负载,因为i5-3470处理器是一个四核处理器,理论上,我只能使用25%的处理器加载两个线程.

为什么我使用两个线程而不是四个线程?
起初,我认为处理器是双核处理器,XD.

Q1:这是我的第一个问题:为什么这两个线程infiniteLoop()可以消耗50%的质量核心CPU容量?

我努力想解决这个问题,但我自己真的没能做到这一点......:X

第二个解决方案

第二种解决方案是完全一样的第一个,不同之处在于我使用clock()time.h替换GetTickCount()功能.在这个解决方案中,我真的需要4个线程来使处理器加载到50%.

是代码.

#include <boost/thread.hpp>
#include "windows.h"
#include <ctime>
#define INTERVAL 10

void infiniteLoop() {
    while (1) {
        clock_t startTime = clock();
        while (clock() - startTime <= INTERVAL)
            ;
        boost::posix_time::millisec sleepTime(INTERVAL);
        boost::this_thread::sleep(sleepTime);
    }
}

int main() {
    boost::thread thread1(infiniteLoop);
    boost::thread thread2(infiniteLoop);
    boost::thread thread3(infiniteLoop);
    boost::thread thread4(infiniteLoop);
    thread1.join();
    thread2.join();
    thread3.join();
    thread4.join();
    char c;
    std::cin >> c;
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案使得处理器的总使用率几乎达到50%,但是通过观察任务管理器 - >性能 - > CPU记录,我发现四个核心的使用并不是均匀分布的,前两个核心的负载几乎是60 %,第三个约为50%,最后一个仅为最大负载的30%.

所以这是我的第二个问题.
Q2:为什么这些核心没有统一加载,这种现象背后是否存在操作系统内部的某种机制?

第三个解决方案

另一个想法是完全阻止两个线程,从而使CPU加载50%.

这是代码.

#include <boost/thread.hpp>
#include "windows.h"
#include <iostream>

void infiniteRunningLoop() {
    while (1) {
        ;
    }
}

int main() {
  boost::thread thread1(infiniteRunningLoop)
  boost::thread thread2(infiniteRunningLoop)
  thread1.join();
  thread2.join();
}
Run Code Online (Sandbox Code Playgroud)

关于三种解决方案的思考

  • 这三种解决方案不是将CPU加载到50%的通用解决方案,因为如果您在系统中运行其他程序,它们也会消耗CPU容量.
  • 该解决方案仅适用于四核处理器,如果要在其他处理器上使用它,例如双核处理器,则必须修改线程数.
  • 这三种解决方案都不是优雅的..XD

那么,问题3:有人可以提供一个优雅的解决方案,可以实现目标,并可在不同类型的处理器之间移植吗?

非常感谢那些通读了这个问题的人,甚至还要感谢那些可能提前回答这个问题的人!

XD

Bal*_*ick 1

我认为您缺少的关键是能够计算处理器的数量。你可以这样做:

SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );
numCPU = sysinfo.dwNumberOfProcessors;
Run Code Online (Sandbox Code Playgroud)

由此得出的计数将与您在任务管理器中看到的数量相同。

如果您将其与现有方法结合起来,您应该会得到一些非常通用的工作。