为什么绘制POT图像比NPOT图像更快?

4
我正在研究画布速度优化问题,发现了这条回答:https://dev59.com/ZlvUa4cB1Zd3GeqPy_5D#7682200
  • 不要使用宽度为奇数的图像。一定要使用2的幂作为宽度。
所以我想知道,这样做为什么更快?
我看过一些帖子解释说,这有助于旧版图形卡(在使用OpenGL等时),但我谈论的是速度,而不是兼容性,并且是关于画布,而不是OpenGL / WebGL。

3
我认为这是因为它可以使mipmap构建更容易-如果您有2的幂次方大小,您只需将大小减半并每隔一个元素选取一个来构建第一个mipmap,再次减半以获得逐渐变小的mipmap:http://en.wikipedia.org/wiki/Mipmap http://www.glprogramming.com/red/chapter09.html#name2 - Patashu
@Patashu,如果我理解正确的话,这有助于“加载”吗? - MiJyn
另一个原因可能是2的因数和除数更容易让计算机处理,因为它们可以通过快速位移进行计算,而不是较慢的取模和除法。虽然我不确定它在哪里发挥作用,但我认为它很重要。 - Patashu
@Patashu,对于3D应用程序,您可能是正确的,但通常它是为了帮助内存消耗。 - Jarrod
@Jarrod 没错,这是个好观点 - 我所想的更与3D相关。 - Patashu
1个回答

1

它更快,因为您可以使用<<运算符而不是*操作符。即执行“向左移动1位”(乘以二)比执行“乘以43”要快。可以通过在图像的每一行末尾添加填充字节(如MS在内存位图中所做的那样)来解决这个限制,但本质上,这是两个指令之间速度差异的结果。

在旧时代的8位320x200(13h模式)中,您可以使用简单的公式索引像素:

pixOffset = xPos + yPos * 320;

但这很慢。一个更好的选择是使用

C

pixOffset = xPos + (yPos * 256) + (yPos * 64)

汇编语言

mov ax, xPos    ;   ax = xPos
mov bx, yPos    ;   bx = yPos
shl bx, 6       ;   bx = yPos * 64
add ax, bx      ;   ax = xPos + (yPos * 64)
shl bx, 2       ;   bx = yPos * 256
add ax, bx      ;   ax = xPos + yPos * 320

这可能看起来有些违反直觉,但是当写得很好时,它只使用单个时钟指令。也就是说,你可以在6个时钟周期内计算出偏移量。当然,流水线和缓存未命中会使情况变得复杂。
在硬件中实现移位寄存器比实现完整的乘法单元要便宜得多,无论是在美元还是晶体管方面。因此,相同数量的晶体管可以用于提供更好的性能,或者可以使用更少的晶体管以获得相同的性能并降低功率消耗。
据我所知,现代处理器的mul(和div)指令是通过查找表来实现的。这在很大程度上缓解了问题,但它也不是没有问题。如果想进一步阅读,请查看Pentium fdiv bug(芯片内的查找表填充错误)。

http://en.wikipedia.org/wiki/Pentium_FDIV_bug

因此,总的来说,这实际上是实现功能所使用的硬件/软件的产物。

这个回答是针对这个问题的吗?这个回答看起来相当... 强烈 :P - Jarrod
:grin: 是的。不幸的是,硬件/软件设计和集成的许多方面都非常复杂。(但是研究和理解它们非常有趣) - enhzflep
谢谢,这确实解决了一些“速度”问题,但据我所知,这只是一个很小的问题,不是吗? - MiJyn
1
非常愉快。是的,看起来这似乎是一个相当小的差异 - 可能在我真正熟悉x86汇编语言的15年中已经减少了。但它非常复杂。将代码优化为使用2的幂次方分辨率更容易。这也是图形硬件(曾经)喜欢的方式。此外,考虑到内存对齐会使其变得更加复杂。你要么(a)承受非对齐内存的更多周期,要么(b)浪费内存对齐它,然后浪费指令来访问它。这会使它在内存中变得更大,导致进一步的缓存未命中。 - enhzflep
好的,还有一个问题,将图像调整大小使其成为POT(未使用的空间将是透明的)是否比使用非POT更快?我猜不是,对吧? - MiJyn
1
是的,这取决于图像的使用方式,如果你在“绘制”透明区域,则可能不会更快。但是,如果您调整UV坐标,只显示可见区域,则可以更快。这是游戏和OpenGL / DirectX采取的方法。即将6x6图像放入8x8位图中,并将UV设置为leftTop = [0,0]和rightBot [0.75,0.75]。如果仍为6x6,则协调员将是leftTop [0,0]和rightBot [1,1] - 此外,画布在支持的情况下确实是硬件加速的,因此调整大小为POT似乎是一个明智的选择。 - enhzflep

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