gpt4 book ai didi

x86 - 为什么mov ah,bh和mov al,bl一起比单指令mov ax,bx快得多?

转载 作者:行者123 更新时间:2023-12-03 13:28:07 26 4
gpt4 key购买 nike

我发现

mov al, bl
mov ah, bh


比快得多

mov ax, bx


谁能解释我为什么?
我在Windows XP下以32位模式在Core 2 Duo 3 Ghz上运行。
使用NASM进行编译,然后与VS2010链接。
Nasm编译命令:

nasm -f coff -o triangle.o triangle.asm


这是我用来渲染三角形的主要循环:

; some variables on stack
%define cr DWORD [ebp-20]
%define dcr DWORD [ebp-24]
%define dcg DWORD [ebp-32]
%define dcb DWORD [ebp-40]

loop:

add esi, dcg
mov eax, esi
shr eax, 8

add edi, dcb
mov ebx, edi
shr ebx, 16
mov bh, ah

mov eax, cr
add eax, dcr
mov cr, eax

mov ah, bh ; faster
mov al, bl
;mov ax, bx

mov DWORD [edx], eax

add edx, 4

dec ecx
jge loop


我可以为整个VS项目提供测试源。

最佳答案

为什么慢
与使用8位寄存器相比,使用16位寄存器比较昂贵的原因是16位寄存器指令是用微码解码的。这意味着在解码期间需要额外的周期,并且在解码时无法配对。
另外,由于ax是部分寄存器,因此将需要一个额外的周期来执行,因为寄存器的顶部需要与对下部的写入结合在一起。
8位写入具有特殊的硬件来加快速度,但16位写入则没有。同样,在许多处理器上,16位指令占用2个周期而不是1个周期,并且它们不允许配对。

这意味着您现在只能执行1,而不是能够在4个周期内处理12条指令(每个周期3个),因为将指令解码为微代码时会出现停顿,而在处理微代码时会出现停顿。

我怎样才能使其更快?

mov al, bl
mov ah, bh


(此代码至少需要2个CPU周期,并且可能使第二条指令停顿,因为在某些(旧)x86 CPU上,您会锁定EAX)
这是发生了什么:


读取EAX。 (周期1)


EAX的低字节已更改(静止周期1)
并将全部值写回到EAX。 (周期1)

EAX被锁定以进行写入,直到第一次写入完全解决为止。 (可能等待多个周期)
对EAX中的高字节重复此过程。 (周期2)


在最新的Core2 CPU上,这并不是什么大问题,因为已经放置了额外的硬件,这些硬件知道 blbh确实不会互相妨碍。

mov eax, ebx


该指令一次移动4个字节,该单个指令将在1个cpu周期中运行(并且可以与其他指令并行配对)。


如果需要快速代码,请始终使用32位(EAX,EBX等)寄存器。
除非必须,否则请尽量避免使用8位子寄存器。
切勿使用16位寄存器。即使您必须在32位模式下使用5条指令,这仍然会更快。
使用movzx reg,...(或movsx reg,...)说明


加快代码
我看到一些加速代码的机会。

; some variables on stack
%define cr DWORD [ebp-20]
%define dcr DWORD [ebp-24]
%define dcg DWORD [ebp-32]
%define dcb DWORD [ebp-40]

mov edx,cr

loop:

add esi, dcg
mov eax, esi
shr eax, 8

add edi, dcb
mov ebx, edi
shr ebx, 16 ;higher 16 bits in ebx will be empty.
mov bh, ah

;mov eax, cr
;add eax, dcr
;mov cr, eax

add edx,dcr
mov eax,edx

and eax,0xFFFF0000 ; clear lower 16 bits in EAX
or eax,ebx ; merge the two.
;mov ah, bh ; faster
;mov al, bl


mov DWORD [epb+offset+ecx*4], eax ; requires storing the data in reverse order.
;add edx, 4

sub ecx,1 ;dec ecx does not change the carry flag, which can cause
;a false dependency on previous instructions which do change CF
jge loop

关于x86 - 为什么mov ah,bh和mov al,bl一起比单指令mov ax,bx快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7031671/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com