【问题标题】:How to keep the CPU usage down while running an SDL program?如何在运行 SDL 程序时降低 CPU 使用率?
【发布时间】:2012-10-07 15:24:26
【问题描述】:

我已经使用 SDL 完成了一个非常基本的窗口,并希望在我按下窗口上的 X 之前一直运行它。

#include "SDL.h"
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main(int argc, char **argv)
{
    SDL_Init( SDL_INIT_VIDEO );
    SDL_Surface* screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 0, 
                                            SDL_HWSURFACE | SDL_DOUBLEBUF );
    SDL_WM_SetCaption( "SDL Test", 0 ); 
    SDL_Event event;
    bool quit = false;
    while (quit != false)
    {
        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                quit = true;
            }
        }
        SDL_Delay(80);
    }
    SDL_Quit();
    return 0;
}

我尝试在 while 子句末尾添加SDL_Delay(),效果很好。

但是,80 毫秒似乎是我可以用来保持程序平稳运行的最高值,即使如此,CPU 使用率也约为 15-20%。

这是做到这一点的最佳方式吗?我是否必须忍受它已经在这一点上吃掉这么多 CPU 的事实?

【问题讨论】:

    标签: c++ multithreading sdl


    【解决方案1】:

    我知道这是一篇较旧的帖子,但我自己在启动一个小演示项目时遇到了 SDL 的这个问题。正如用户 'thebuzzsaw' 所说,最好的解决方案是使用 SDL_WaitEvent 来减少事件循环的 CPU 使用率。

    如果任何人在未来寻求快速解决方案,以下是您的示例中的外观。希望对您有所帮助!

    #include "SDL.h"
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    int main(int argc, char **argv)
    {
        SDL_Init( SDL_INIT_VIDEO );
        SDL_Surface* screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 0, 
                                                SDL_HWSURFACE | SDL_DOUBLEBUF );
        SDL_WM_SetCaption( "SDL Test", 0 ); 
        SDL_Event event;
        bool quit = false;
        while (quit == false)
        {
            if (SDL_WaitEvent(&event) != 0) {
                switch (event.type) {
                case SDL_QUIT:
                quit = true;
                break;
                }
            }
        }
        SDL_Quit();
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      我肯定会尝试完全阻塞的功能(例如SDL_WaitEvent)。我在 Qt 中有一个 OpenGL 应用程序,我注意到 CPU 使用率徘徊在 0% 和 1% 之间。在“使用”期间(移动相机和/或产生动画),它可能会飙升至 4%。

      我正在开发自己的窗口工具包。我注意到当我使用阻塞事件循环时,我可以实现类似的 CPU 使用率。这将使您可能依赖的任何计时器变得复杂,但使用这种新方法实现计时器并不是非常困难。

      【讨论】:

        【解决方案3】:

        我刚刚想出了如何将游戏中的 CPU 使用率从 50% 降低到 SDL_Delay() 就足够了。

        我所做的是: 加载图片时使用SDL_DisplayFormat(),这样blitting会更快。这使其 CPU 使用率降低到 30% 左右。

        所以我发现对游戏背景(大的一体式 .png 文件)进行 blitting 占用了我的 CPU 资源。我在 Internet 上搜索了一个解决方案,但我发现的都是相同的答案 - 只需使用 SDL_Delay()。最后,我发现问题非常简单——SDL_DisplayFormat() 正在将我的 24 位图像转换为 32 位。所以我将我的显示 BPP 设置为 24,这使 CPU 使用率达到了 ~20%。将它降低到 16 位解决了我的问题,现在 CPU 使用率低于 10%。

        当然,这意味着色彩细节的损失,但由于我的游戏是一个简单的 2D 游戏,没有太详细的图形,这没关系。

        【讨论】:

          【解决方案4】:

          要真正理解这一点,您需要了解线程。在线程应用程序中,程序一直运行到它正在等待某个东西,然后它告诉操作系统其他东西可以运行。本质上,您正在使用SDL_Delay 命令执行此操作。如果没有任何延迟,我怀疑您的程序将以接近 100% 的容量运行。

          只有在其他命令花费大量时间的情况下,您应该在延迟语句中放置的时间量才有意义。一般来说,我会将延迟设置为与测试 poll 命令所需的时间类似,但不超过 10 毫秒。将会发生的情况是操作系统将至少等待该时间长度,从而允许其他应用程序在后台运行。

          至于您可以做些什么来改善这一点,好吧,看起来您可以做的事情并不多。但是,请注意,如果正在运行的另一个进程占用大量 CPU 资源,您的程序的份额将会减少。

          【讨论】:

          • SDL中只使用一个线程正常吗?你有SDL_PushEventSDL_AddTimer,那为什么不去多线程呢?
          • 使用 10 毫秒会使 CPU 使用率接近 60%。我很好奇 GTK 是如何管理这个的,因为它创建类似的虚拟窗口根本不会影响 CPU 使用率。
          • @DyP 即使程序没有线程,操作系统也是。操作系统负责测量 CPU 使用率,因此它会报告高于其他情况的报告。
          • 每 1000/x ms 花费一些时间从消息循环轮询一次只是浪费(CPU)时间。在大多数(几乎所有)情况下,长时间睡眠(SDL_Delay)并不是一个好的解决方案——同步还有什么用?我想到的唯一一个你不想无限期睡觉的例子是常规任务。你可以使用另一个线程甚至SDL_AddTimer 来做到这一点。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-01
          • 1970-01-01
          • 2023-03-27
          • 2016-06-11
          • 1970-01-01
          • 1970-01-01
          • 2013-02-07
          相关资源
          最近更新 更多