清除内存块(或SDL表面)的最快方法是什么?

7

我目前正在使用SDL开发一个项目,它基本上在屏幕上绘制和移动图像(表面)。

要移动图像而不留下轨迹,您必须首先清除屏幕表面,就像glClear()一样,我目前是用一个简单的for循环来迭代表面的像素(还在表面上画一个黑色框或memset)来做到这一点。

虽然以前的解决方案对于小表面效果良好,但随着表面变得越来越大,它们变得越来越慢,因此我正在寻找最快的方法来清除(零)一个内存块。

此外,一个朋友指出使用SIMD指令可以非常快地完成工作,但我上一次做ASM是在8085上,任何关于此的见解也可能有用。

2个回答

15

最快的方法是使用memset函数。

memset(ptr, 0, length);

这个功能会自动在支持它的架构上使用SIMD技术*。你不可能超越它。它已经受到内存限制,因此它会尽可能快地写入零。我不知道是谁告诉你对于更大的块,memset 更慢,但你应该停止听那个人的话。

*有一些工具链不提供快速的 memset,但你很可能没有在使用这样的工具链。


1
我不知道是谁告诉你memset在处理更大的块时会变慢,但你应该停止听从那个人的建议。实际上,这只适用于SDL函数,我没有彻底测试过memset。有一些工具链不能提供快速的memset,例如一些PIC MCU工具链(显然不是这种情况)。 - NeonMan
在PIC微控制器上运行SDL有点奇怪,毕竟PIC没有SIMD。 - Dietrich Epp
个人经验是memset通常相当慢。我查看过的源代码只是进行字节设置。对于更大的区域,我自己编写的代码使用较大的写入来处理中间部分(在必要时仅在末尾使用小写入),效果非常好。但具体情况因人而异。 - Brian Knoblauch
@BrianKnoblauch:你看过哪些实现?我已经查看了Linux(glibc)和Mac OS X(libc)的库,它们都有一些实现:一个是C语言,然后是几个汇编语言。这两个库甚至都有三种不同的x86实现:一个是x86,一个是x86+SSE2,还有一个是完全用汇编语言编写的x86-64。如果你能在你的平台上展示给我一个基准测试,那就太好了。 - Dietrich Epp

3

你应该尝试使用memset,其实现应该经过高度优化,以利用您系统上可用的任何指令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接