简体   繁体   English

为什么 Mac 上的 SDL 比 Linux 慢这么多?

[英]Why is SDL so much slower on Mac than Linux?

I am working on a single-threaded graphical program that renders using SDL2 .我正在开发一个使用 SDL2 呈现的单线程图形程序 See the end for a smaller example.有关较小示例,请参见结尾。

It runs on both an old Linux machine and a somewhat less old Mac.它可以在旧的 Linux 机器和不太旧的 Mac 上运行。 The Linux computer has 1.60GHz processors while the Mac's processors are 2.2GHz. Linux 计算机有 1.60GHz 的处理器,而 Mac 的处理器是 2.2GHz。 The SDL version on Linux is 2.0.8, while the SDL version of the Mac is 2.0.10. Linux 上的 SDL 版本是 2.0.8,而 Mac 上的 SDL 版本是 2.0.10。 On both computers I compiled with clang++ using optimization flags -O3 and -flto .在两台计算机上,我使用优化标志-O3-flto使用clang++进行编译。 I invoked the executable with ./intergrid -fullscreen -pixel-size 3 (essentially, I had the program draw very many pixels.)我用./intergrid -fullscreen -pixel-size 3调用了可执行文件(本质上,我让程序绘制了很多像素。)

For some reason, the slower Linux computer executed the program with no sweat, while the Mac took several seconds to render the first frame.出于某种原因,较慢的 Linux 计算机毫不费力地执行了该程序,而 Mac 则需要几秒钟才能渲染第一帧。 The Mac was faster than the Linux machine, as expected, when I used the -no-draw flag to disable graphics.正如预期的那样,当我使用-no-draw标志禁用图形时,Mac 比 Linux 机器快。

EDIT: The Linux computer has "Intel Haswell Mobile" for graphics and the Mac lists "Intel Iris Pro 1536 MB."编辑:Linux 计算机具有用于图形的“Intel Haswell Mobile”,而 Mac 则列出“Intel Iris Pro 1536 MB”。

Here is a minimal reproducible example:这是一个最小的可重现示例:

#include <SDL2/SDL.h>
#include <stdio.h>

int main(void)
{
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);

    SDL_Window *window = SDL_CreateWindow(
        "Example",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        0, 0,
        SDL_WINDOW_SHOWN);
    SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Rect viewport;
    SDL_RenderGetViewport(renderer, &viewport);

    // The screen is not rendered to unless this is done:
    SDL_Event event;
    while (SDL_PollEvent(&event))
        ;

    Uint32 ticks_before = SDL_GetTicks();
    for (int x = 0; x < viewport.w - 10; x += 10) {
        for (int y = 0; y < viewport.h - 10; y += 10) {
            // I just chose a random visual effect for this example.
            SDL_Rect square;
            square.x = x;
            square.y = y;
            square.w = 10;
            square.h = 10;
            SDL_SetRenderDrawColor(renderer, x % 256, y % 256, 255, 255);
            SDL_RenderFillRect(renderer, &square);
        }
    }
    Uint32 ticks_after = SDL_GetTicks();
    printf("Ticks taken to render: %u\n", ticks_after - ticks_before);

    SDL_RenderPresent(renderer);

    SDL_Delay(500);

    // I Won't worry about cleaning stuff up.
}

I compiled this on Mac and Linux with clang++ -O3 -flto <filename> -lSDL2 .我在 Mac 和 Linux 上用clang++ -O3 -flto <filename> -lSDL2编译了这个。 When I ran the program on the Mac, it printed:当我在 Mac 上运行该程序时,它打印出:

Ticks taken to render: 849

The program on Linux printed: Linux 上的程序打印:

Ticks taken to render: 4

That's a gigantic difference!这是一个巨大的差异!

@keltar found a solution that is good enough for me, but they have not yet posted it as an answer, so I will. @keltar 找到了一个对我来说足够好的解决方案,但他们尚未将其发布为答案,所以我会发布。 For some reason, SDL2's Metal back end is immensely slow, so the solution is to use the OpenGL back end.出于某种原因,SDL2 的 Metal 后端非常慢,因此解决方案是使用 OpenGL 后端。 I accomplished this by calling SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl") if I found that the default driver was Metal (using SDL_GetRendererInfo .)如果我发现默认驱动程序是 Metal(使用SDL_GetRendererInfo SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl") ,我通过调用SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")来完成此SDL_GetRendererInfo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM