相关疑难解决方法(0)

加速x64汇编器ADD循环

我正在研究很长整数的乘法运算(大约100,000个十进制数字).作为我的图书馆的一部分,我要添加两个长数字.

分析表明我的代码在add()和sub()例程中运行的时间高达25%,因此尽可能快地运行它们非常重要.但我还没有看到太大的潜力.也许你可以给我一些帮助,建议,见解或想法.我会测试它们然后再回复你.

到目前为止,我的添加例程进行了一些设置,然后使用了8次展开的循环:

mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
adc rax, r10
mov QWORD PTR [rcx+r11*8-64], rax
Run Code Online (Sandbox Code Playgroud)

然后是7个具有不同偏移的块然后循环.

我之前尝试从内存中加载值,但这没有帮助.我想那是因为好的预取.我使用Intel i7-3770 Ivy Bridge 4核CPU.但我想编写适用于任何现代CPU的代码.

编辑:我做了一些时间:它在大约2.25个周期/单词中增加1k个单词.如果我移除ADC,那么只剩下MOV,它仍然需要大约1.95个周期/字.所以主要的瓶颈似乎是内存访问.一个库memcpy()工作在大约0.65个周期/单词,但只有一个输入,而不是两个.我猜,因为它使用了SSE寄存器,所以速度要快得多.

一些问题:

  • 使用"加载,加载,添加,存储"结构或"加载,添加到内存"帮助是否有用?到目前为止,我的测试没有显示出任何优势.
  • 像往常一样,没有SSE(2,3,4)的预期帮助?
  • 寻址(缩放索引加基数加偏移)是否会严重影响?我可以ADD r11, 8改用.
  • 循环展开怎么样?我读到展开对Sandy Bridge架构很糟糕(Agner Fog http://www.agner.org/optimize/).它是首选还是避免?
  • (编辑)我可以使用SSE寄存器从存储器加载和存储更大块的字,并有效地与通用寄存器和SSE寄存器交换字吗?

我非常感谢任何评论.

optimization assembly x86-64 bignum arbitrary-precision

11
推荐指数
1
解决办法
1059
查看次数