Yic*_*hao 7 c++ operating-system cpu-usage
最初的问题来自编程之美的第1.1章
我的第一次尝试没有考虑多核和多线程,所以它不起作用,但它提供了这样的想法:如果我们希望处理器加载一半,我们可以创建一个无限循环,它占用一半的时间,并占用处理器另一半.
我将跳过第一次尝试的细节.
在我的第二次努力中,情况进展顺利,但仍有一些困扰我的问题.
以下片段是第一个可能的解决方案.它使用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)
那么,问题3:有人可以提供一个优雅的解决方案,可以实现目标,并可在不同类型的处理器之间移植吗?
非常感谢那些通读了这个问题的人,甚至还要感谢那些可能提前回答这个问题的人!
XD
我认为您缺少的关键是能够计算处理器的数量。你可以这样做:
SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );
numCPU = sysinfo.dwNumberOfProcessors;
Run Code Online (Sandbox Code Playgroud)
由此得出的计数将与您在任务管理器中看到的数量相同。
如果您将其与现有方法结合起来,您应该会得到一些非常通用的工作。