我正在尝试针对特定的 Kaby Lake CPU (i5-7300HQ) 优化以下子例程,理想情况下,与原始形式相比,代码速度至少快 10 倍。该代码在 16 位实模式下作为软盘式引导加载程序运行。它在屏幕上显示一个十位数的十进制计数器,从 0 - 9999999999 计数然后停止。
我查看了 Agner 的微体系结构和汇编优化指南、 指令性能表和英特尔的优化参考手册。
到目前为止,我能够做的唯一明智的优化是将loop指令交换为dec + jnz,在此处进行解释。
另一种可能的优化可能是交换lodsbfor mov + dec,但我发现的关于它的信息一直存在冲突,有些人说它有一点帮助,而另一些人则认为它实际上可能会损害现代 CPU 的性能。
我还尝试切换到 32 位模式并将整个计数器保留在一个未使用的寄存器对中以消除任何内存访问,但在读入一点后我意识到这十位将立即被缓存,并且 L1 缓存之间的延迟差异和寄存器只有大约三倍,所以绝对不值得以这种格式使用计数器的额外开销。
(编者注:add reg延迟为 1 个周期,add [mem]延迟约为 6 个周期,包括 5 个周期的存储转发延迟。如果[mem]像视频 RAM 那样不可缓存,则更糟。)
org 7c00h
pos equ 2*(2*80-2) ;address on screen
;init
cli
mov ax,3
int 10h
mov …Run Code Online (Sandbox Code Playgroud)