为什么 SDL 在 Mac 上比在 Linux 上慢这么多?
Why is SDL so much slower on Mac than Linux?
我正在研究 a single-threaded graphical program that renders using SDL2。请参阅末尾以获取更小的示例。
它既可以在一台旧 Linux 机器上运行,也可以在一台不太旧的 Mac 机器上运行。 Linux 计算机的处理器为 1.60GHz,而 Mac 的处理器为 2.2GHz。 Linux上的SDL版本是2.0.8,而Mac上的SDL版本是2.0.10。在两台计算机上,我使用优化标志 -O3
和 -flto
使用 clang++
编译。我用 ./intergrid -fullscreen -pixel-size 3
调用了可执行文件(本质上,我让程序绘制了很多像素。)
出于某种原因,速度较慢的 Linux 计算机毫不费力地执行了程序,而 Mac 需要几秒钟来渲染第一帧。正如预期的那样,Mac 比 Linux 机器快,当我使用 -no-draw
标志禁用图形时。
编辑:Linux 计算机有 "Intel Haswell Mobile" 图形和 Mac 列表 "Intel Iris Pro 1536 MB."
这是一个最小的可重现示例:
#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.
}
我在 Mac 和 Linux 上用 clang++ -O3 -flto <filename> -lSDL2
编译了这个。当我 运行 Mac 上的程序时,它打印:
Ticks taken to render: 849
Linux 上打印的程序:
Ticks taken to render: 4
这是天壤之别!
@keltar 找到了一个对我来说足够好的解决方案,但他们还没有将其作为答案发布,所以我会的。由于某种原因,SDL2 的 Metal 后端非常慢,因此解决方案是使用 OpenGL 后端。如果我发现默认驱动程序是 Metal(使用 SDL_GetRendererInfo
。)
,我会通过调用 SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")
来完成此操作
我正在研究 a single-threaded graphical program that renders using SDL2。请参阅末尾以获取更小的示例。
它既可以在一台旧 Linux 机器上运行,也可以在一台不太旧的 Mac 机器上运行。 Linux 计算机的处理器为 1.60GHz,而 Mac 的处理器为 2.2GHz。 Linux上的SDL版本是2.0.8,而Mac上的SDL版本是2.0.10。在两台计算机上,我使用优化标志 -O3
和 -flto
使用 clang++
编译。我用 ./intergrid -fullscreen -pixel-size 3
调用了可执行文件(本质上,我让程序绘制了很多像素。)
出于某种原因,速度较慢的 Linux 计算机毫不费力地执行了程序,而 Mac 需要几秒钟来渲染第一帧。正如预期的那样,Mac 比 Linux 机器快,当我使用 -no-draw
标志禁用图形时。
编辑:Linux 计算机有 "Intel Haswell Mobile" 图形和 Mac 列表 "Intel Iris Pro 1536 MB."
这是一个最小的可重现示例:
#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.
}
我在 Mac 和 Linux 上用 clang++ -O3 -flto <filename> -lSDL2
编译了这个。当我 运行 Mac 上的程序时,它打印:
Ticks taken to render: 849
Linux 上打印的程序:
Ticks taken to render: 4
这是天壤之别!
@keltar 找到了一个对我来说足够好的解决方案,但他们还没有将其作为答案发布,所以我会的。由于某种原因,SDL2 的 Metal 后端非常慢,因此解决方案是使用 OpenGL 后端。如果我发现默认驱动程序是 Metal(使用 SDL_GetRendererInfo
。)
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")
来完成此操作