我正在调查画布速度优化,我找到了这个答案:https://stackoverflow.com/a/7682200/999400
- 不要使用奇数宽度的图像。始终使用宽度作为2的幂。
所以我想知道,为什么这会更快?
我看到的帖子解释说这有助于旧显卡(当使用OpenGL等时),但我说的是速度,而不是兼容性,还有画布,而不是OpenGL / WebGL。
答案 0 :(得分:1)
它更快,因为你可以使用<<运算符而不是* oprator。即,执行“左移1”(乘以2)比执行“多次乘43”更快。可以通过在图像的每一行的末尾添加填充字节来解决这个限制(正如MS在内存位图中所做的那样),但实际上,这是两条指令之间速度差异的结果。
在8bit 320x200(模式13h)的旧时代,您可以使用简单的公式索引像素:
pixOffset = xPos + yPos * 320;
但这是懒散的。一个更好的选择是使用
<强> C 强>
pixOffset = xPos + (yPos * 256) + (yPos * 64)
<强> ASM 强>
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
所以最后,它实际上是用于实现功能的硬件/软件的人工制品。