【问题标题】:Why is drawing POT images faster than NPOT images?为什么绘制 POT 图像比 NPOT 图像更快?
【发布时间】:2013-06-14 15:32:22
【问题描述】:

我正在研究画布速度优化,我找到了这个答案:https://stackoverflow.com/a/7682200/999400

  • 不要使用奇数宽度的图像。始终使用宽度作为 2 的幂。

所以我想知道,为什么这更快?

我看到一些帖子解释说这有助于旧显卡(使用 OpenGL 等),但我说的是速度,而不是兼容性,以及画布,而不是 OpenGL/WebGL。

【问题讨论】:

  • 我认为这是因为它使 mipmap 的构建更容易 - 如果你有两个大小的幂,你可以将大小减半并取其他所有元素来构建第一个 mipmap,再减半,等等依次变小mipmaps:en.wikipedia.org/wiki/Mipmapglprogramming.com/red/chapter09.html#name2
  • @Patashu,所以如果我理解正确,那么它对 加载 有帮助吗?
  • 另一个原因可能是 2 的因数和除数对于计算机来说更容易处理,因为与较慢的模数和除法相比,它们可以通过快速位移来计算。虽然我不确定它究竟在哪里发挥作用,但我怀疑它很重要。
  • @Patashu 对于 3D 应用程序,您可能是正确的,但通常它有助于减少内存消耗。
  • @Jarrod 对,这是一个很好的观点——我在想的是与 3D 更相关。

标签: javascript performance canvas


【解决方案1】:

它更快,因为您可以使用

在 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 个时钟周期内计算偏移量。当然,流水线和缓存未命中会使场景复杂化。

在硬件中实现移位寄存器也比在 $$ 和晶体管中的完整乘法单元便宜得多。因此,可以使用相同数量的晶体管来提供更好的性能,或者可以使用更少的晶体管来提供相同的性能,但功耗更低。

AFAIK,现代处理器的 mul(和 div)指令是在查找表的帮助下实现的。这在很大程度上缓解了问题,但也不是没有问题。如需进一步阅读,请查看 Pentium fdiv 错误(在芯片内错误填充了查找表)

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

所以最后,它本质上是用于实现功能的硬件/软件的人工制品。

【讨论】:

  • 这个答案是针对这个问题的吗?这个答案看起来很...激烈:P
  • :咧嘴笑:是的。不幸的是,硬件/软件设计和集成的许多方面都很紧张。 (但调查和理解很有趣)
  • 谢谢,这确实解决了一些“速度”问题,但据我所知,这是一个很小的问题,不是吗?
  • 很高兴。是的,它似乎确实是一个相当小的差异 - 自从我真正熟悉 x86 汇编以来,可能在 15 年中已经减少了。但它相当复杂。优化代码以使用两种分辨率的幂更容易。这也是图形硬件(过去?)喜欢的方式。另外,考虑到内存对齐会使它有些复杂。您要么必须(a)为未对齐的内存遭受更多周期,要么(b)浪费内存对齐它,然后浪费指令来访问它。这会使其在内存中变得更大,从而导致更多的缓存未命中。
  • 是的,它会更快,这取决于图像的使用方式。如果您“绘制”透明区域,则可能不是。但是,如果您调整 UV 坐标以便只显示可见区域,那么是的,它会更快。这是游戏和 openGL/dirextX 采用的方法。即 6x6 图像将被放入 8x8 位图中,UV 设置为 leftTop = [0,0] 和 rightBot[0.75,0.75]。如果它仍然是 6x6,则坐标将是 leftTop [0,0] 和 rightBot [1,1] - 此外,画布 硬件在支持的情况下加速,所以看起来很谨慎将大小调整为 POT 的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-09
相关资源
最近更新 更多