High cpu loading. C++/sfml

High cpu loading. C++/sfml

本文关键字:sfml C++ loading cpu High      更新时间:2023-10-16

我的程序将处理器加载 80%。前段时间我在 GPU 上遇到了同样的问题,我通过计时器解决了它。CPU负载约为50-60%,现在为80%。我做错了什么?我无法解决它的问题。

#include <fstream>
#include <SFML/Graphics.hpp>
#include <ctime>
using namespace std;
char * readFile(char * filePath, unsigned int &lengthBuffer, fstream &f) {
f.open(filePath, ios::in | ios::app | ios::binary);
f.seekg (0, f.end);
lengthBuffer = f.tellg();
f.seekg (0, f.beg);
char * fileBuffer = new char[lengthBuffer];
f.read(fileBuffer, lengthBuffer);
f.close();
return fileBuffer;
}
char * writeFile(char * fileBuffer, char * filePath, unsigned int &lengthBuffer, fstream &f, bool &fileCreated){
filePath[23] += 1;
f.open(filePath, ios::out | ios::app | ios::binary);
f.write(fileBuffer, lengthBuffer);
filePath[23] -= 1;
fileCreated = 1;
f.close();
return fileBuffer;
}
void removeFile(char * filePath, bool &fileCreated) {
filePath[23] += 1;
remove(filePath);
filePath[23] -= 1;
fileCreated = 0;
}
unsigned int mouse(unsigned int &funcSelector, bool &mouseLeft, sf::RenderWindow &window) {
mouseLeft = sf::Mouse::isButtonPressed(sf::Mouse::Left);
sf::Vector2i mouse = sf::Mouse::getPosition(window);
if (mouseLeft & mouse.y < 100) {
funcSelector = 1 + mouse.x/100;
}
return funcSelector;
}
int main(){
sf::RenderWindow window(sf::VideoMode(500, 400), "COT++", sf::Style::Titlebar);
sf::VertexArray points(sf::Points, 3000);
sf::Event event;
fstream f;
bool mouseLeft, fileCreated = 0;
unsigned int n = 0, funcSelector = 0, lengthBuffer = 0;
float start = 0, now = 0, x = 0.f, y = 1.f, pos = 0.f;
char * fileBuffer, filePath[30] = "c:/users/79994/desktop/a.exe";
while (x < 500.f){
points[n].position = sf::Vector2f(x + pos, y + pos);
points[n].color = sf::Color::Green;
x += 1.f;
n += 1;
if (x == 500.f & y < 100.f){
x = 0.f;
y += 100.f;
}
}
x = 100.f, y = 1.f;
while (x < 600.f){
points[n].position = sf::Vector2f(x + pos, y + pos);
points[n].color = sf::Color::Green;
y += 1.f;
n += 1;
if (y > 101.f){
x += 100.f;
y = 1.f;
}
}
while (window.isOpen())
{
while (window.pollEvent(event)) {
if((clock()-start) > 50){
start = clock();
switch(funcSelector){
case 5: window.close();
break;
case 1: if (lengthBuffer == 0){
fileBuffer = readFile(filePath, lengthBuffer, f);
}    
break;
case 2: if (lengthBuffer > 0 & fileCreated == 0) {
writeFile(fileBuffer, filePath, lengthBuffer, f, fileCreated);
}
break;
case 3: removeFile(filePath, fileCreated);  
break;
}
mouse(funcSelector, mouseLeft, window);
window.clear();
window.draw(points);
window.display();
}
}
}
return 0;
}

附言 "看起来你的帖子主要是代码;请添加更多细节" - 我想我描述了足够的细节。

这取决于你想做什么。对于您给出的简单示例,您可以使用waitEvent而不是pollEvent.我建议检查waitEvent是否适合您的需求,但看起来会。

但是,如果您坚持使用pollEvent,请继续阅读!

您的while(window.pollEvent(event))循环 100% 的时间全速运行,不停地轮询,即使看起来您的目标只是每隔50个时钟"工作"。(时钟与实际度量单位的相关性不一致,除了CLOCKS_PER_SEC,这是实现定义的......而且std::clock可能与墙壁时间无关...当这不是一个有意义的值时,CLOCKS_PER_SEC可能会被硬编码为 100 万......但我离题了。无论您如何跟踪时间,对于编写的代码,您的问题都会存在,尽管您可能需要一些其他计时机制。

下面是一个可能的解决方案,只需对代码进行最少的更改。取代:

while (window.pollEvent(event)) {
if((clock()-start) > 50){

与以下内容:

while (window.pollEvent(event)) {
const auto delta = clock() - start;
if (delta < 50) {
std::this_thread::sleep_for(std::chrono::microseconds(
static_cast<int>(1E6 * (50 - delta) / CLOCKS_PER_SEC)));
} else {

它的作用是,不是不断地叫window.pollEvent(event),它会叫它,如果需要的话睡一会儿,然后做一些工作。

这种方法也有一些缺点,但它应该让你开始思考这个问题。

您还需要#include <chrono>(或者,如果您不使用C++11或更晚的时间,您可以找到其他几乎正确的睡眠方式)。

仅通过查看代码来尝试猜测或多或少是困难和不精确的。 应尝试使用探查器分析代码。

PS:您似乎在"readFile"和"writeFile"中也有内存泄漏,您在其中分配了一个缓冲区,但再也不会释放它。

char * readFile(char * filePath, unsigned int &lengthBuffer, fstream &f) {
// [...]
char * fileBuffer = new char[lengthBuffer];
// here you allocated memory on the heap, but you'll never free it.
// [...]
return fileBuffer;
}

我还认为根本不使用这些动态字符数组和 C 文件。只需使用 std::string 和 std::ostream。ostream 适用于更多的 STL 和字符串,您不必关心其内存使用情况和潜在的内存泄漏。它会自行清理,而不是字符数组。