找回密码
 欢迎注册
楼主: 无心人

[擂台] 大数运算基选择测试

[复制链接]
 楼主| 发表于 2008-4-9 07:51:49 | 显示全部楼层


不公开代码怎么能证明快?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 11:21:22 | 显示全部楼层


俺是不会采用你们的进制的
即使你们的快,能快多少呢?

看到liangbch的blog了
希望能坚持写下去

我的数论变换也希望自己能写下去
我写的不是资料找不到,相关资料上500页呢
如果遇到困难了,肯定是懒惰的原因
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 12:01:03 | 显示全部楼层
原帖由 无心人 于 2008-4-9 11:21 发表


俺是不会采用你们的进制的
即使你们的快,能快多少呢?

  快了很多,而不是一点儿。


  公布代码与否,是作者的自由,特别是一些领先对手的技术,作者一般不愿公布。
至于能否证明是不是更优,没有别的办法,只有靠相互间的信任了。我以我的信誉担保,我的代码没有作弊,如果你确实不相信,也没有办法。

  以后,可以考虑提供静态库,供使用者来测试,但静态库也无法保护算法,只能凭借加密,这需要时间。如果大家确实需要它,我可以考虑以后提供给大家一个加密的静态库。

  当然,在适当的时候,我也可能公开我的代码。
  
  我在20#提到的6个函数已经全部完成,说明如下:

UInt480x480_ALU:
  使用经典的算法,算法类似于GMP中的 mul_basecase.c,汇编代码可参照gmp-4.2.2\mpn\x86\pentium\mul_basecase.asm, 只不过是完全的循环展开式,无需递增地址变量,也没有比较/跳转指令。

UInt480x480_ALU2:类似我在 x86上128位二进制乘法最快速算法征解(http://bbs.emath.ac.cn/thread-216-1-1.html) 102楼做法,减少了ADD指令的使用次数,也减少了内存写的次数,速度有所提升,在内存性能较差的PC(如PM) 上,性能提升明些。


  UInt480x480_MMX:类似我在 x86上128位二进制乘法最快速算法征解(http://bbs.emath.ac.cn/thread-216-1-1.html) 76楼的代码,也类似楼主在 本帖中4#的做法,使用完全的循环展开,无需递增 地址变量,也没有比较/跳转指令。

UInt480x480_base30_ALU:
  基为$2^30$,有点类似UInt480x480_ALU2,采用完全的循环展开。

UInt480x480_base30_MMX:
  基为$2^30$,乘法和加法使只使用MMX寄存器。每个循环步 使用 1次32bit 乘。 目前性能最有优异的版本,性能大大提升。


UInt480x480_base30_SSE2:
  基为$2^30$,乘法和加法主要在XMM2寄存器中进行,也少量使用MMX寄存器。结果和我过去的预测不同,在P4 上运行,性能大幅领先于UInt480x480_base30_ALU,在PM上运行,性能却低于UInt480x480_base30_ALU。

  结论:不过是PM还是PIV,UInt480x480_base30_MMX 都是最快的版本,我之前一直请看了使用 MMX的SSE2指令。在x86上128位二进制乘法最快速算法征解 中,我的76楼的程序脱颖而出。让我第一次见识了使用 MMX寄存器 SSE2指令的威力。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 12:06:55 | 显示全部楼层
贴上测试结果:
在PIV 2.6G cpu上的测试结果:

Test function: UInt480x480_ALU(..) 1000000 times...
Elapsed time: 1262.801 ms

Test function: UInt480x480_ALU2(..) 1000000 times...
Elapsed time: 1240.831 ms

Test function: UInt480x480_MMX(..) 1000000 times...
Elapsed time: 989.584 ms

Test function: UInt480x480_base30_ALU(..) 1000000 times...
Elapsed time: 1236.035 ms

Test function: UInt480x480_base30_MMX(..) 1000000 times...
Elapsed time: 393.707 ms

Test function: UInt480x480_base30_SSE2(..) 1000000 times...
Elapsed time: 544.485 ms

可以看到,在PIV CPU,采用基为$2^30$的版本,竟达到同样使用MMX寄存器的基为 $2^32 $版本的250%,这可不是快了一点点了。


再贴上PM 1.7G 上的测试结果。
Test function: UInt480x480_ALU(..) 1000000 times...
Elapsed time: 935.995 ms

Test function: UInt480x480_ALU2(..) 1000000 times...
Elapsed time: 892.114 ms

Test function: UInt480x480_MMX(..) 1000000 times...
Elapsed time: 846.011 ms

Test function: UInt480x480_base30_ALU(..) 1000000 times...
Elapsed time: 695.499 ms

Test function: UInt480x480_base30_MMX(..) 1000000 times...
Elapsed time: 562.144 ms

Test function: UInt480x480_base30_SSE2(..) 1000000 times...
Elapsed time: 912.002 ms
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 13:52:14 | 显示全部楼层


MMX 32bit乘和我的预期差别太大啊
一个双字乘是12个周期
12 * 225 * 1000000 / 2.6G = 0.137ms

==============================
你的480代表480bit么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 14:18:38 | 显示全部楼层
由那个帖子:x86上128位二进制乘法最快速算法征解 76#的结果:

Test function: UInt128x128To256_SSE2_76F(..) 10000000 times...
Elapsed time: 395.657 ms

得到的结论是 1千万 * 4*4=395.657 ms,故平均每次乘是0.00247285625微妙。
按此换算。15*15*0.00247285625*100万=556.39265625ms,
这里的结果是 989.584ms,因为在本例中,没有那么多的寄存器保存中间结果,故需要大量的内存写,时间从估计值556.3926562 变为 989.584 应属正常。没什么不正常呀。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 14:21:57 | 显示全部楼层
把程序里所有base30的去掉
源代码给我
===========================
为什么有疑惑呢
因为无论进制如何
乘法每个循环都是一个乘两个加
而且都不需要考虑进位
一个乘法延迟PM是3,P4是8 P4D是9
加法都是1-2的
不考虑别的因素
其结构都是一致的
所以应该32和30的时间差不多
如果你能优化30到这么大
也应该优化32到更多,毕竟32的字节少
==================================
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 14:50:43 | 显示全部楼层
mbinmul3:
             movd mm2, dword ptr [edi]
             lea edi, [edi+4]
             movd mm3, dword ptr [ebx]                        
             pmuludq mm2, mm1
             paddq mm0, mm3
             paddq mm0, mm2
             movd dword ptr [ebx], mm0


本想对 yaos的代码进行测试,却发现这是个未经调试过的版本,根本不能工作。当执行的上面的最后指令时,内存写溢出。
建议yaos以后别发未经调试过的代码。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 14:53:07 | 显示全部楼层
原帖由 无心人 于 2008-4-9 14:21 发表
乘法每个循环都是一个乘两个加
...


这句话不对。
你完全没有悟到其中的道理,所以base30的代码肯定不能给你了,至于其他的那3个函数的代码,我会在今晚公开。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 16:49:36 | 显示全部楼层
错在哪里?

===========================
对了, 你把我代码改成这个就没问题了
先别考虑清零。看执行时间多少?
void  lMul_yaos(uint32  *result, uint32  *left, uint32  *right, uint32 sLeft, uint32 sRight)
{
__asm          {
             mov edx, sLeft
             mov  esi, dword ptr [left]
             mov  edi, dword ptr [right]
             mov  ebx, dword ptr [result]
mbinmul2:
             mov eax, ebx
             pxor mm0, mm0
             mov ecx, sRight                        
             movd mm1, dword ptr [esi]
             movd mm4, edi
mbinmul3:
             movd mm2, dword ptr [edi]
             lea edi, [edi+4]
             movd mm3, dword ptr [ebx]                        
             pmuludq mm2, mm1
             paddq mm0, mm3
             paddq mm0, mm2
             movd dword ptr [ebx], mm0
             psrlq mm0, 32
             lea ebx, [ebx+4]
             sub ecx, 1
             jnz mbinmul3
             movd edi, mm4
             movd dword ptr [ebx], mm0
             mov ebx, eax
             lea esi, [esi+4]
             lea ebx, [ebx+4]
             sub edx, 1
             jnz mbinmul2
             emms
             }
}
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-6-24 20:01 , Processed in 0.061809 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表