我还在研究C++中任意长整数的例程.到目前为止,我已经为64位Intel CPU实现了加/减和乘法.
一切正常,但我想知道我是否可以通过使用SSE来加快速度.我浏览了SSE文档和处理器指令列表,但我找不到任何我认为可以使用的内容,原因如下:
SSE有一些整数指令,但大多数指令处理浮点.看起来它不是设计用于整数(例如,是否有较小的整数比较?)
SSE的想法是SIMD(相同的指令,多个数据),因此它提供了2或4个独立操作的指令.另一方面,我希望有一个像128位整数加(128位输入和输出)的东西.这似乎不存在.(但是?在AVX2中可能?)
整数加法和减法既不处理输入也不处理输出.因此,手动操作非常麻烦(因而也很慢).
我的问题是:我的评估是正确的还是有什么我忽略的?长整数例程可以从SSE中受益吗?特别是,它们可以帮助我编写更快的添加,子或mul例程吗?
当我正在进行快速ADD循环(加速x64汇编器ADD循环)时,我正在使用SSE和AVX指令测试内存访问.要添加,我必须读取两个输入并产生一个输出.所以我编写了一个虚拟例程,它将两个x64值读入寄存器,然后将其写回存储器而不进行任何操作.这当然没用,我只做了基准测试.
我使用一个展开的循环,每个循环处理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
Run Code Online (Sandbox Code Playgroud)
然后我将其升级到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
Run Code Online (Sandbox Code Playgroud)
后来我使用了AVX(每个寄存器256位).我有2个这样的块:
vmovdqa ymm0, YMMWORD PTR [rdx+r11*8-64]
vmovdqa ymm1, YMMWORD PTR [r8+r11*8-64]
vmovdqa YMMWORD PTR [rcx+r11*8-64], ymm0
Run Code Online (Sandbox Code Playgroud)
到目前为止,还不那么引人注目.有趣的是基准测试的结果:当我在1K + 1K = 1K 64位字(即两次输入的8 kb和一次输出的8KB)运行三种不同的方法,我得到了奇怪的结果.以下每个时序用于处理两次64字节输入到64字节输出.
我的问题是:为什么AVX方法比SSE2方法慢(虽然不是很多)?我预计它至少会与之相提并论.使用YMM寄存器会花费多少额外的时间吗?内存已对齐(否则会获得GPF).
有没有人对此有解释?