编写一段代码使 CPU 利用率在 50%左右

本文介绍了一种通过交替执行指令和睡眠来精确控制CPU使用率为50%的方法,并提供了两种实现方式,一种是通过循环和固定睡眠时间实现,另一种是利用C++11的chrono库动态调整循环时间。
该文章已生成可运行项目,

1. CPU 的使用率

  1. 要让 CPU 保持一直使用,即让它一直 取指执行取指执行 才能维持高的 CPU 使用率
  • 取指执行 操作:
 mov         dword ptr [ebp-70h],0  
 jmp         main+0D8h (0E09BC8h)  
 mov         eax,dword ptr [ebp-70h]  
 add         eax,1  
 mov         dword ptr [ebp-70h],eax  
 cmp         dword ptr [ebp-70h],27100h 
  1. 如果 CPU 没有执行 取指执行 的操作,那么 CPU 就不使用,CPU 的使用率就会低,
  • 比如:
Sleep(1)

或者

调用 IO 输入输出

但是, IO 操作会调用 system call,导致很多不可控的内核运行时间。

  1. 所以,使用取指执行 使用CPU,使用 Sleep 睡眠函数让 CPU 静止不操作。让两者的操作(很短的时间,比如 10 个微秒)各占一半,那么就可以让 CPU 使用率在 50%

2. 简单的解法

1. Linux 系统
#include <iostream>
#include <vector>
#include <unistd.h>

int main(){
	// 不同的计算机需要修改 900000 这个值
	std::vector<int> v(900000, 0);

	// 取指执行和睡眠的时间各占一半
	while(true) {
		// 取指执行
        for (auto& a : v) {
        }
        // 睡眠 μs
        usleep(10000);
	}
	return 0;
}

  • 编译运行
chen@chen229:~/xm/scripts> g++ -o main main.cc  -std=c++11
chen@chen229:~/xm/scripts> ./main

在这里插入图片描述

  • 查看 CPU 使用率
chen@chen229:~> ps -aux | grep main
chen     22659 49.6  0.0  13128  1244 pts/3    S+   14:28   0:35 ./main
chen     22675  0.0  0.0   8312   876 pts/1    S+   14:29   0:00 grep --color=auto main

在这里插入图片描述

  • 可以看到在CPU 使用率 49.6%
    在这里插入图片描述

3. 比较通用的解法,换了计算机也不用改什么

1. Linux 系统
  • 首先先看一下 C++11 标准库的 <chrono> 的使用
#include <iostream>
#include <vector>
#include <chrono>

int main() {

	// 记录初始时间
    std::vector<int> v(300000, 5);
	auto startTime = std::chrono::high_resolution_clock::now();

	for (auto& a : v) {

    }

	// 记录结束时间
	auto stopTime = std::chrono::high_resolution_clock::now();
	// 求时间差
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stopTime - startTime);

	// 输出时间: μs
	std::cout << "time: " << duration.count() << " microseconds\n";
	
	return 0;
}
  • 运行
lenovo@lenovo-PC MINGW64 /e/zhiyong/5. chenqifeng/2. codes/3. init/1_DebyeGas/temp
$ g++ -o main main.cc -std=c++11

lenovo@lenovo-PC MINGW64 /e/zhiyong/5. chenqifeng/2. codes/3. init/1_DebyeGas/temp
$ ./main.exe
time: 5000 microseconds
  • 最后的程序:
#include <iostream>
#include <chrono>
#include <unistd.h>

int main() {

	const int SLEEP_TIME = 10000;
	
    while(true) {
		// 记录初始时间
		auto start = std::chrono::high_resolution_clock::now();
		// 取指执行的时间为 10000 μs
		while(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start).count() < SLEEP_TIME) {
		}
		// 睡眠的时间为 10000 μs
		usleep(SLEEP_TIME);
    }

	return 0;
}

测试:(和上面的一样,我就直接复制下来了)

  • 编译运行
chen@chen229:~/xm/scripts> g++ -o main main.cc  -std=c++11
chen@chen229:~/xm/scripts> ./main

在这里插入图片描述

  • 查看 CPU 使用率
chen@chen229:~> ps -aux | grep main
chen     22659 49.6  0.0  13128  1244 pts/3    S+   14:28   0:35 ./main
chen     22675  0.0  0.0   8312   876 pts/1    S+   14:29   0:00 grep --color=auto main

在这里插入图片描述

  • 可以看到在CPU 使用率 49.6%
    在这里插入图片描述

3. 参考

《编程之美》

本文章已经生成可运行项目
要实现这个 C++ 程序,需要完成几个关键任务:调整 CPU 利用率50%,并在 1 小时内保持在 45% - 55% 范围内的时间不超过 180 秒;每隔 10 分钟(包含程序运行第一秒)输出系统时间、CPU 序列号和当前 CPU 利用率。 以下是一个可能的实现代码: ```cpp #include <iostream> #include <chrono> #include <thread> #include <ctime> #include <fstream> #include <string> #include <vector> // 模拟 CPU 负载 void busyLoop() { for (volatile int i = 0; i < 1000000; ++i); } // 获取当前 CPU 利用率 double getCPUUsage() { // 这里需要实现获取 CPU 利用率的逻辑 // 简单示例,实际需要根据系统调用实现 return 50.0; } // 获取系统时间 std::string getSystemTime() { auto now = std::chrono::system_clock::now(); std::time_t currentTime = std::chrono::system_clock::to_time_t(now); return std::ctime(&currentTime); } // 获取 CPU 序列号 std::string getCPUSerialNumber() { // 这里需要实现获取 CPU 序列号的逻辑 // 简单示例,实际需要根据系统调用实现 return "1234567890"; } int main() { auto startTime = std::chrono::high_resolution_clock::now(); auto endTime = startTime + std::chrono::hours(1); int deviationTime = 0; // 程序运行第一秒输出信息 std::cout << "System Time: " << getSystemTime(); std::cout << "CPU Serial Number: " << getCPUSerialNumber(); std::cout << "CPU Usage: " << getCPUUsage() << "%" << std::endl; while (std::chrono::high_resolution_clock::now() < endTime) { auto loopStartTime = std::chrono::high_resolution_clock::now(); busyLoop(); auto loopEndTime = std::chrono::high_resolution_clock::now(); auto loopDuration = std::chrono::duration_cast<std::chrono::milliseconds>(loopEndTime - loopStartTime).count(); std::this_thread::sleep_for(std::chrono::milliseconds(loopDuration)); double cpuUsage = getCPUUsage(); if (cpuUsage < 45 || cpuUsage > 55) { deviationTime += std::chrono::duration_cast<std::chrono::seconds>(loopEndTime - loopStartTime).count(); } auto currentTime = std::chrono::high_resolution_clock::now(); auto elapsedTime = std::chrono::duration_cast<std::chrono::minutes>(currentTime - startTime).count(); if (elapsedTime % 10 == 0) { std::cout << "System Time: " << getSystemTime(); std::cout << "CPU Serial Number: " << getCPUSerialNumber(); std::cout << "CPU Usage: " << cpuUsage << "%" << std::endl; } if (deviationTime > 180) { std::cerr << "CPU usage deviation exceeded 180 seconds." << std::endl; return 1; } } return 0; } ``` ### 代码说明: 1. **`busyLoop` 函数**:模拟 CPU 负载,通过一个简单的循环来占用 CPU 时间。 2. **`getCPUUsage` 函数**:获取当前 CPU 利用率,这里只是简单返回 50.0,实际需要根据系统调用实现。 3. **`getSystemTime` 函数**:获取当前系统时间。 4. **`getCPUSerialNumber` 函数**:获取 CPU 序列号,这里只是简单返回一个示例序列号,实际需要根据系统调用实现。 5. **`main` 函数**: - 记录程序开始时间和结束时间。 - 在程序运行第一秒输出系统时间、CPU 序列号和当前 CPU 利用率。 - 通过 `busyLoop` 和 `std::this_thread::sleep_for` 来调整 CPU 利用率50%。 - 记录 CPU 利用率偏离 50% 上下 5% 的时间。 - 每隔 10 分钟输出系统时间、CPU 序列号和当前 CPU 利用率。 - 如果偏离时间超过 180 秒,输出错误信息并退出程序。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值