L1性能

    在知道了L1的大小以后,接着测试L1的性能参数。对L1,我们关心的是每个周期可以完成的操作个数和每个操作需要多少个周期才能完成。至于L1每秒可以把多少MB的数据塞到寄存器中则不具有可比性。每周期可以完成的操作个数一般叫做产出或吞吐量(Throughput),完成一个操作需要的周期数叫做延迟(Latency)。在这里我们都用周期数作为比较的单位。

    测量产出的方法很简单。只要尽可能快地向读写端口提交无关的操作,读写端口就可以以最高的速度完成这些请求。所以我们用顺序操作来测量产出(顺序读、顺序写和顺序复制)。

    测量延迟要麻烦一些。延迟是指从提交操作到得到数据之间需要等待的时间。为了得到延迟数据,必须保证前一个操作完成之前,不提交下一个操作。这在通用寄存器组上是可以实现的。我们关于读操作的测试核心语句如下:

    mov   eax,   [eax]

也就是每次从内存中读入下一次要访问的地址。由于在读操作完成之前,不可能获得下一次要访问的地址,所以可以保证上一个读操作完成之前下一个操作不会提交。这个语句要正确执行,必须有2个前提:(1)把所有内存单元初始化成一个环形指针链;(2)在进入循环前把起始地址加载到EAX。其中条件(2)在以前讨论测试函数时已经说过了。条件(1)是由一个C函数完成的,操作也很简单,请自己看源码,在此不详细讨论。

    对写操作,没有办法找到这样的相关指令,所以不测试写操作的延迟,只测试产出。

    对复制操作,用下面的核心指令序列测试延迟:

mov edi, [eax]
mov [eax+edx], edi
mov eax, edi

其中EDX存储的是MemSize,在前面讨论测试函数的文章中也有说明。由于写操作没有适当的方法测量延迟,这样得出的延迟并不是复制操作的真正延迟,仅可作为参考。

    对MMX和SSE,同样没有合适的指令可以测量延迟,所以也不测试。

    在后面的测试中,把上面所说的相关的读操作测试和复制操作测试叫做RL和CL或者RL/04和CL/04,可以理解为“Read Latency”和“Copy Latency”。

下面是测试结果:

L1Performance_01.gif (10001 bytes)

每个测试的第一列表示循环展开因子。可见在进行了充分的循环展开后,测试结果间的差异可以忽略,可以不考虑循环附加开销的影响。

    从表中可以看出,PIII基本上可以每个周期完成一个32位或64位的L1读操作,而128位操作需要约2个周期,说明其L1和寄存器的接口可能是64位的。其L1的延迟是3个周期。而写操作由于未能达到理论最大值,可能是由于“写回”策略的影响导致的。根据缓存原理,对采取写回策略的缓存,如果发生“写未命中”事件,将会伴随一个内存读操作,这会降低操作速度。但这里用的是反复操作同一块内存的方法,应该说写未命中的比例不会很大,而测试结果与理论值有10~25%的偏差,可能还有其它的影响因素(如:诡异的Store Address单元)。复制操作由于要使用写操作,其实际能达到的产出就更低了。复制操作的延迟仅可作参考。


Leading Cloud Surveillance, Recording and Storage service; IP camera live viewing

Leading Enterprise Cloud IT Service; cloud file server, FTP Hosting, Online Storage, Backup and Sharing

Powered by FirstCloudIT.com, a division of DriveHQ, the leading Cloud IT and Cloud Surveillance Service provider since 2003.