这个asm比使用eax寄存器的相应部分慢得多。那是为什么?
jmp .l2
.l1:
dec ESI
.l2:
cmp ESI, 0
jne .l1
jmp .l2
.l1:
dec EAX
.l2:
cmp EAX, 0
jne .l1
答案 0 :(得分:5)
性能取决于在运行此代码之前和之后使用的EAX和ESI。根据架构,CPU可以并行处理在不同寄存器上运行的指令;在同一寄存器上运行的代码必须阻止。
(除了信任编译器之外,我没有任何更具体的建议:它知道分配寄存器以利用并行性的正确方法,但我不知道。)
答案 1 :(得分:1)
,Boath的代码段或多或少都有一些执行速度。您可以通过在rutine之前执行指令 rdtsc 并在rutine之后检测执行速度来测量(计数)执行CPU时钟。当然,boath rutines必须从EAX和ESI寄存器中的某个值开始。不要使用巨大的循环值,因为任务调度程序可以在循环执行过程中中断当前任务,您将得到错误的结果。但是,如果某些测量结果偏离当前任务被任务调度程序中断了很多,则必须忽略该结果。
编辑: TESTs
我在这里进行了两项测试,以便每个人都可以查看结果:
var
StartTicks :Int64;
EndTicks :Int64;
procedure TForm9.ButtonEAXClick(Sender: TObject);
begin
asm
rdtsc
mov dword ptr [StartTicks], eax
mov dword ptr [StartTicks + 4], edx
//Start test
mov eax, 10000
@Loop:
dec eax
cmp eax, 0
jnz @Loop
//End test
rdtsc
mov dword ptr [EndTicks], eax
mov dword ptr [EndTicks + 4], edx
end;
caption := IntToStr(EndTicks - StartTicks);
end;
procedure TForm9.ButtonESIClick(Sender: TObject);
begin
asm
rdtsc
mov dword ptr [StartTicks], eax
mov dword ptr [StartTicks + 4], edx
//Start test
mov esi, 10000
@Loop:
dec esi
cmp esi, 0
jnz @Loop
//End test
rdtsc
mov dword ptr [EndTicks], eax
mov dword ptr [EndTicks + 4], edx
end;
caption := IntToStr(EndTicks - StartTicks);
end;
现代CPU上的10000次循环在使用EAX或ESI执行rutine之间不会产生任何差异。
答案 2 :(得分:0)
在某些情况下,使用AX / EAX的指令可能会更短。没有那么大的交易,因为它是在8088天的WAAAY(由于8位数据总线和慢速内存访问)处理器浪费了很多时间,只是试图填充管道来运行下一条指令。
答案 3 :(得分:-1)
寄存器的速度取决于你用它们做什么,因为每个寄存器都有自己的电路。例如,ecx连接到计数器电路,因此如果用作计数器它会更快,eax很好地连接到ALU,因此它是数学任务的最佳寄存器。当然现在你可以使用ecx作为数学和eax作为计数器,但在早期的处理器时代程序员没有这种自由。 事实上,esi用于内存访问,因此它与内存的连接“更好”(请通过术语,我无法表达自己更好)。