当我在处理快速ADD循环(如何提速x64汇编ADD循环)时,我使用SSE和AVX指令测试内存访问。为了执行加法操作,我需要读取两个输入并产生一个输出。因此,我编写了一个虚拟程序,将两个x64值读入寄存器中,并将其中一个写回内存,而没有进行任何操作。显然,这是无用的,只是为了进行基准测试。
到目前为止,还没有什么特别惊人的地方。有趣的是基准测试结果:当我在1k + 1k = 1k 64位字(即两次8kb的输入和一次8kb的输出)上运行三种不同的方法时,得到了奇怪的结果。以下每个时间都是处理两个64字节输入以生成64字节输出的时间。
我使用展开的循环每次处理64字节,它由8个类似于以下块的块组成:
mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
mov QWORD PTR [rcx+r11*8-64], rax
然后我将其升级为SSE2。现在我使用4个类似于此的块:
movdqa xmm0, XMMWORD PTR [rdx+r11*8-64]
movdqa xmm1, XMMWORD PTR [r8+r11*8-64]
movdqa XMMWORD PTR [rcx+r11*8-64], xmm0
后来我使用了AVX(每个寄存器256位)。我有两个这样的块:
vmovdqa ymm0, YMMWORD PTR [rdx+r11*8-64]
vmovdqa ymm1, YMMWORD PTR [r8+r11*8-64]
vmovdqa YMMWORD PTR [rcx+r11*8-64], ymm0
到目前为止,还没有什么特别惊人的地方。有趣的是基准测试结果:当我在1k + 1k = 1k 64位字(即两次8kb的输入和一次8kb的输出)上运行三种不同的方法时,得到了奇怪的结果。以下每个时间都是处理两个64字节输入以生成64字节输出的时间。
- x64寄存器方法大约需要15个周期/64字节
- SSE2方法大约需要8.5个周期/64字节
- AVX方法大约需要9个周期/64字节