找回密码
 欢迎注册
查看: 18134|回复: 16

[讨论] 高速大数乘法 pk HugeCalc

[复制链接]
发表于 2009-6-22 00:08:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
由于工作需要,写了个大数乘法算法(作为RSA的一部分)
跟 HugeCalc V8.0.0.0对比了下,发现我的程序速度要快上许多。

下面是统计数据:
1、只累计乘法算法时间
我的HugeLib:
for( int times = 0; times < 1000000; ++times )
{
    HugeMul();
}
HugeCalc:
for( int times = 0; times < 1000000; ++times )
{
    c = ( a * b );
}

结果:
128位*128位(按8位 = 1字节,即16字节) 耗时(单位为秒):
HugeLib:0.0863
HugeCalc:1.841

256位*256位
HugeLib:0.219
HugeCalc:2.310

512位*256位
HugeLib:0.385
HugeCalc:2.714

512位*512位
HugeLib:0.698
HugeCalc:4.151

2、累计输入数据初始化、乘法计算和结果转字符串
HugeLib:
for( int times = 0; times < 1000; ++times )
{
DWORD dwRet= Init( "0xA48B637BDD34BFAB24567F79751903A49AE4C92E1113745C78DAB49413DC71A6C89A0A21F3C794D4DC46ED0C6CB8DBECE4ACEA39E7A591F96E8D071A8423065A", "0x748B637BDD34BFAB24567F79751903A49AE4C92E1113745C78DAB49413DC71A6C89A0A21F3C794D4DC46ED0C6CB8DBECE4ACEA39E7A591F96E8D071A84230655" );
    HugeMul();
    const char* p = GetRetStr();
}
HugeCalc:
for( int times = 0; times < 1000; ++times )
{
CHugeIntX a( "0xA48B637BDD34BFAB24567F79751903A49AE4C92E1113745C78DAB49413DC71A6C89A0A21F3C794D4DC46ED0C6CB8DBECE4ACEA39E7A591F96E8D071A8423065A" );
CHugeIntX b( "0x748B637BDD34BFAB24567F79751903A49AE4C92E1113745C78DAB49413DC71A6C89A0A21F3C794D4DC46ED0C6CB8DBECE4ACEA39E7A591F96E8D071A84230655" );

CHugeIntX   c = ( a * b );
c.GetStr();
}
结果:
512位*512位耗时:
HugeLib:0.002968
HugeCalc:0.167497


两者都是通过调用动态库方式进行比较的。
附件里含测试工程,包括调用HugeCalc的头文件.h,Lib和Dll,以及我的HugeLib的头文件.h,Lib和Dll文件。
由于HugeCalc v8试用版的缘故,还需要放在 "CopyrightByGuoXianqiang" 目录下进行……

#include "hugeLib.h"
#pragma comment( lib, "hugeLib.lib" )
#include "Include/HugeCalc.h" // 公共接口
#include "Include/HugeInt.h" // 10进制系统
#include "Include/HugeIntX.h" // 16进制系统
#pragma comment( lib, "HugeCalc.lib" )

HugeLib & Test_Project.rar

368.62 KB, 下载次数: 46, 下载积分: 金币 -1 枚, 经验 1 点, 下载 1 次

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-6-22 00:19:01 | 显示全部楼层
理论上乘法速度还可以再优化10%左右^^
有空我再搞一下,嘿嘿

对了,忘记说了,上面测试使用的cpu是我可怜的 AMD Sempron 1.75GHz, 内存1G(这不是瓶颈)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-6-22 07:42:56 | 显示全部楼层
可惜,你的测试程序写得不对.简单重复乘法操作会被编译器优化的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-6-22 07:52:34 | 显示全部楼层
下载了你的附件,发现你的测试代码不公平。

1、对 HugeCalc 的测试,你是在循环体内进行构造、析构的,这本身需要耗用一定的时间;
2、在 HugeCalc 中,“c = ( a * b )”可用“c.Mul(a,b)”替换,应更高效。

你可以看看增大输入后,两者耗时的上升趋势如何?曲线曲率越小的越优。

关于 HugeCalc,它设计定位在超大数的快速运算,
在数据结构以及算法上尽量优先满足超大数的计算,
所以对小规模的计算并未做太多的优化,
但这个情形不会长久下去,
在下次内核大改动时会一并考虑的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-6-22 08:16:07 | 显示全部楼层
呵呵,没有注意还附带测试程序:
LZ的函数
HugeMul();
的调用方法很奇怪.
我修改了一下代码:

  1.         DWORD dwRet = Init( "0x9A34567890123456789012345678901234567890123456789012345678901234", "0x9A34567890123456789012345678901234567890123456789012345678901234" );
  2. for( int times = 0; times < 100000; ++times )
  3. {
  4.         HugeMul();
  5. }
复制代码

  1.     CHugeIntX a( "0x9A34567890123456789012345678901234567890123456789012345678901234" );
  2.     CHugeIntX b( "0x9A34567890123456789012345678901234567890123456789012345678901234" );
  3.     CHugeIntX c;

  4. for( int times = 0; times < 100000; ++times )
  5. {
  6.         c.Mul(a,b);
  7. }
复制代码
然后为了防止编译器优化引起的影响,选择Debug方式编译.
运行结果HugeLib 0.0414秒,HugeCalc0.0271秒
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-6-22 08:17:58 | 显示全部楼层
其实我觉得要做比较,最好直接拿像PowMod之类比较复杂的运算比较好一些. 这样,其它意外因素影响会小一些
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-6-22 09:27:31 | 显示全部楼层
如5楼所言,我改成那个样子,并用Debug方式编译,在我Intel Pentium Dual E2180 2.00GHz系统上,
使用我的算法,耗时0.0581秒,使用HugeCalc,耗时0.139秒。和你的测试结果完全不同。奇哉,怪也。

我测了一下我算法执行的计算机指令周期数,512位*512位,我的算法经历了 3139 个指令周期
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-6-22 09:31:09 | 显示全部楼层
4楼的同志,不太了解你的算法库,刚刚接触而已。工作需要,本来想直接用你的,可是发现有限制,所以只好自己写了,郁闷。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-6-22 09:33:19 | 显示全部楼层
4楼,有点不明白,为啥你那大数转换为字符串输出,要花那么多时间。希望你尽快完善哈^^ 总体来说你的软件还是很不错的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-6-22 12:32:06 | 显示全部楼层
HugeCalc 的输入输出的效率并不低,是经过特别优化过的。

如果仅仅为RSA服务,完全可以开一个足够大的固定数组,
而 HugeCalc 并不仅仅为RSA服务,所以其内部数据存放空间完全是动态的,包括输出转换出的字符串,
所以你在循环体里反复调用它,实际上它在反复申请空间。

而输出一般并不需要在循环体内反复调用,
你可以将它们单独分离出来对比测试一下,
这样测试才更科学。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-4-27 11:37 , Processed in 0.052518 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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