Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ [C+;+;][SFML 2.2]奇怪的性能问题-移动鼠标会降低CPU使用率_C++_Performance_Sfml - Fatal编程技术网

C++ [C+;+;][SFML 2.2]奇怪的性能问题-移动鼠标会降低CPU使用率

C++ [C+;+;][SFML 2.2]奇怪的性能问题-移动鼠标会降低CPU使用率,c++,performance,sfml,C++,Performance,Sfml,在过去的两周左右的时间里,我一直在做一个2D地图编辑器,但我遇到了一个非常奇怪的问题。例如,当我试图优化我的代码时,通过为本来应该是函数的函数创建函数,我做了一些事情,使我的CPU使用率达到了顶峰。我试着注释出我认为最有可能是罪魁祸首的代码的不同部分(滚动、渲染、其他计算),但没有用。我认为问题可能只是试图从不同的函数中调用东西,但为了使其尽可能模块化,我真的很喜欢这种功能。 自从我将其与之进行比较的文件以来,我所做的另一个主要更改是,我将所有变量移植到了一个外部CPP文件中,因为将变量作为全局


在过去的两周左右的时间里,我一直在做一个2D地图编辑器,但我遇到了一个非常奇怪的问题。例如,当我试图优化我的代码时,通过为本来应该是函数的函数创建函数,我做了一些事情,使我的CPU使用率达到了顶峰。我试着注释出我认为最有可能是罪魁祸首的代码的不同部分(滚动、渲染、其他计算),但没有用。我认为问题可能只是试图从不同的函数中调用东西,但为了使其尽可能模块化,我真的很喜欢这种功能。

自从我将其与之进行比较的文件以来,我所做的另一个主要更改是,我将所有变量移植到了一个外部CPP文件中,因为将变量作为全局变量使其更易于从不同的函数中使用。这可能是一个非常简单的问题,但我一辈子都不明白为什么会发生。

使用原始代码,我可以获得大约2-3%的CPU使用率。使用新的代码,我得到了20-35%左右,但是,如果我移动鼠标,它将下降到6-8%左右。

tl;dr:在尝试使用函数优化我的代码之后,我不知何故牺牲了我的性能,并发现了一个奇怪的怪癖,移动鼠标可以大大降低CPU使用率

//大多数变量在外部文件中声明
void editorLoop()
{
/***************************/
//查看用户想要做什么
/***************************/
std::cout>openOrNewFile;
/************************/
//创建一个新文件
/***********************/
如果(openOrNewFile=='n'| | openOrNewFile=='n')
{
createMap();
}
/***********************/
//退出程序
/**********************/
else if(openOrNewFile=='e'| | openOrNewFile=='e')
{
返回;
}
/************************/
//打开现有文件
/***********************/
else if(openOrNewFile=='o'| | openOrNewFile=='o')
{
openMap();
}
/**********************/
//无效输入
/*********************/
其他的
{
std::cout-screenSizeX*0.95)和&(mousePositionLocal.xscreenSizeY*0.096)和&(mousePositionLocal.ystd::cout我敢打赌,你的CPU是四核的。你看到的CPU百分比来自Windows任务管理器(或其他使用Windows性能计数器的应用程序)。我怀疑这是因为你有一个单线程游戏循环,不间断运行,帧间无休眠。因此,你的“20-35%”CPU实际上是你的程序在你的芯片上占据了一个完整的核心。这是任何游戏循环中想要以尽可能高的帧速率渲染的典型例子

我怀疑你的显卡上有“移动鼠标”生成与其他窗口游戏类似的性能特征。移动鼠标时,Windows图形的优先级高于游戏窗口,并暂停游戏循环的渲染。因此,当鼠标四处移动时,代码仍在运行,但帧速率要低得多。draw()或.display()都可以由于图形系统必须在游戏窗口外处理绘图请求,调用被阻止。因此,游戏循环会被阻止并使用更少的CPU

我的建议是在游戏窗口中添加一个帧速率计数器。它可以显示最后一秒累计的帧数(需要一些额外的整数变量、时间函数和一些除法来计算帧速率)。我猜当鼠标移动时,你会看到帧速率计数器变慢


另外,在internet上搜索“代码分析工具”。Visual Studio的某些版本具有内置功能。它们应该位于代码花费大部分时间的位置。

一个简单的游戏循环,在该循环中,您不想对CPU进行跟踪,它可能类似于:

time last_render = now();
while( app_is_running ) {
  Event e;
  // eat all events.  Ideally, more important than rendering,
  // and should take only a little bit of time:
  while ( get_event(&e) ) {
    process_event(e); // <- note, does not render, should be **cheap**
  }
  // frame limit code:
  while (now()-last_render < frame_limit) {
    Event e;
    if (wait_for_event(&e, (frame_limit-delta)/2))
      process_event(e);
  }
  last_render = now(); // stamp before rendering
  render(); // also includes other game state updates.
}
time last_render=now();
同时(应用程序正在运行){
事件e;
//吃掉所有事件。理想情况下,比渲染更重要,
//而且只需要一点时间:
while(获取事件(&e)){

process_event(e);//不知道sfml是什么,但是您正在
while(gameWindow.isOpen())
中循环,而不是在
while(gameWindow.pollEvent(event))中阻塞
,因此我不知道它如何不运行CPU。因为没有任何东西会停止CPU,CPU将继续运行。有趣的是,如果没有事件发生,也不会发生重画,这意味着没有事件的动画(或者你有什么)不起作用…将
pollEvent
替换为
waitEvent
可能会解决您的问题,但即使这样也不正确,除非您强制“自事件”处理非用户来源的更新(如动画)。SFML代表“简单快速的多媒体库”-这只是一个开源库。有趣的是,这是文档中推荐的语法,也是我在另一个文件中使用的语法(这个文件没有太大的性能问题).为了这个编辑器,waitEvent可能会有所帮助,但我希望将其用作其他一些项目的核心,因此我想看看是否会出现更好的解决方案。谢谢!你是否在鼠标移动时打印内容?这样就可以了。我正在更新两个变量(位置X和位置Y),但我没有打印任何内容。我确实会检查鼠标是否在某些范围内,但在测试性能时,鼠标是否在范围内似乎不会产生影响。此外,问题不在于性能低(我自己可以处理这些问题:D),但当它很高时。考虑到没有阻塞操作,您的CPU肯定会被固定在这样的循环中。您可以进入睡眠状态,但应用程序在运行时不会响应事件
time last_render = now();
while( app_is_running ) {
  Event e;
  // eat all events.  Ideally, more important than rendering,
  // and should take only a little bit of time:
  while ( get_event(&e) ) {
    process_event(e); // <- note, does not render, should be **cheap**
  }
  // frame limit code:
  while (now()-last_render < frame_limit) {
    Event e;
    if (wait_for_event(&e, (frame_limit-delta)/2))
      process_event(e);
  }
  last_render = now(); // stamp before rendering
  render(); // also includes other game state updates.
}