当前位置: 代码迷 >> 汇编语言 >> 一个关于mov占用时钟周期的有关问题
  详细解决方案

一个关于mov占用时钟周期的有关问题

热度:1931   发布时间:2013-02-26 00:00:00.0
一个关于mov占用时钟周期的问题。
mov edx,dword ptr [ecx+edx*4+8]
mov eax,dword ptr [eax+14h]
lea eax,[eax+edx*8]

我不知道[ecx+edx*4+8]这个里面的乘法和加法是不是也要占用时钟周期?
这3句要占用多少时钟周期呢?

------解决方案--------------------------------------------------------
Microsoft (R) Macro Assembler Version 6.11 06/03/08 21:01:15
tt.asm Page 1 - 1


.386

 00000000 code segment use32
assume cs:code
 00000000 start:
 00000000 5 8B 54 91 08 mov edx,dword ptr [ecx+edx*4+8]
 00000004 4 8B 40 14 mov eax,dword ptr [eax+14h]
 00000007 2 8D 04 D0 lea eax,[eax+edx*8]

 000A code ends
end start
------解决方案--------------------------------------------------------
指令周期在不同的cpu上都有差别,即使是同一个型号的不同cpu之间也应该有差别,不同型号的cpu必然有差别,俺上学时看过一本书,讲的是代码极端速度优化的,开始时就指明了不要全信资料上说的,我还照着做了几个实验,果然是那样。
------解决方案--------------------------------------------------------
指令时钟周期在原理上讲的和实际运行是有一定差别。
------解决方案--------------------------------------------------------
各种指令的周期与CPU有关,你可以利用rdtsc来测一下,用类似下面的写法(注意地址有效性,以免发生异常):
rdtsc
mov ebx, eax
mov eax, dword ptr [esi+ecx*4+8] 
mov eax, dword ptr [esi+14h] 
lea eax, [eax+edx*8] 
rdtsc
sub eax, ebx

rdtsc指令是取处理器从reset开始经历了多少个周期,返回值是eax和edx组成的64位数,低两位固定为0。该指令需要80H个周期。测试某一条指令的周期可以在两次rdtsc之间重复执行若干次要测试的指令,然后计算平均值。
------解决方案--------------------------------------------------------
1 时钟周期与指令周期是不同的!指令周期应该是与CPU类型无关的,所以指令周期在不同的CPU上是一样的;但时钟周期就不一样了,有的CPU流水线等不同,一个时钟周期可以完成的指令数可能是1或小于1,也有可能是大于1;
2 指令周期由至少二个部分时钟周期决定:存储器访问周期与CPU处理的时钟(粗略认为是主频吧)
3 所有指令一定占用了机器周期,好在我们可以用指令周期替代更复杂的,与机器相关(如CPU)的周期,如一楼所说的例子一样.
------解决方案--------------------------------------------------------
MASM里输出的时钟周期数是死记硬背下来的,是很老的处理器上的典型数据。
从它的输出例子来看,MASM 6.11里的时钟周期数应该还是386时代的数字(也许更早),与今天的处理器相比已经差异太大了,以此作为优化的依据有盲人摸象的可能性。:)
比如它说:
mov ax,offset table 需要 4个
lea ax,table 则需要 8 个
而 idiv table 更是夸张的用到了超过 177 个时钟周期。

这显然是严重过时的数据。
从486以来的处理器,mov和lea的典型时钟周期数都是1,最差的情况也是2(源地址中包括两个寄存器)。
在Pentium+的超标量架构中,象mov、lea这种常用指令的等效执行时间甚至会小于1个时钟周期。
而idiv指令,据《i486 microprocessor programmer's reference manual》的数字,32除以32是27/最多28个时钟周期,64除以32是43/最多44个时钟周期。在PentiumIII以来的处理器中,不会超过15个时钟周期(没有准确数字,我需要先测试一下)。
  相关解决方案