我刚刚注意到我的一段代码在复制内存时表现出不同的性能。测试表明,如果目标缓冲区的地址大于源地址,则内存复制性能会下降。听起来很荒谬,但以下代码显示了差异(Delphi):
const MEM_CHUNK = 50 * 1024 * 1024;
ROUNDS_COUNT = 100;
LpSrc := VirtualAlloc(0,MEM_CHUNK,MEM_COMMIT,PAGE_READWRITE);
LpDest := VirtualAlloc(0,MEM_CHUNK,MEM_COMMIT,PAGE_READWRITE);
QueryPerformanceCounter(LTick1);
for i := 0 to ROUNDS_COUNT - 1 do
CopyMemory(LpDest,LpSrc,MEM_CHUNK);
QueryPerformanceCounter(LTick2);
// show timings
QueryPerformanceCounter(LTick1);
for i := 0 to ROUNDS_COUNT - 1 do
CopyMemory(LpSrc,LpDest,MEM_CHUNK);
QueryPerformanceCounter(LTick2);
// show timings
这里 CopyMemory 是基于 MOVSD 的。结果 :
开始内存带宽测试...
LpSrc 0x06FC0000
LpDest 0x0A1C0000
src->dest 传输:5242880000 字节在 1,188 秒 @4,110 GB/s。
dest->src 传输:5242880000 字节在 0,805 秒 @6,066 GB/s。
src->dest 传输:5242880000 字节在 1,142 秒 @4,275 GB/s。
dest->src 传输:5242880000 字节在 0,832 秒 @5,871 GB/s。
在两个系统上尝试过,无论重复多少次,结果都是一致的。
从来没有见过这样的事情。无法谷歌它。这是一种已知的行为吗?这只是另一个与缓存相关的特性吗?
更新:
以下是页面对齐缓冲区和 MOVSD 正向 (DF=0) 的最终结果:
开始内存带宽测试...
LpSrc 0x06F70000
LpDest 0x0A170000
src->dest 传输:5242880000 字节在 0,781 秒 @6,250 GB/s。
dest->src 传输:5242880000 字节在 0,731 秒 @6,676 GB/s。
src->dest 传输:5242880000 字节在 0,750 秒 @6,510 GB/s。
dest->src 传输:5242880000 字节,0,735 秒 @6,640 GB/s。
src->dest 传输:5242880000 字节,0,742 秒 @6,585 GB/s。
dest->src 传输:5242880000 字节在 0,750 秒 @6,515 GB/s。
... 等等。
这里的传输速率是恒定的。