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

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

[复制链接]
 楼主| 发表于 2008-4-9 17:30:24 | 显示全部楼层
25结论似乎是错误的 抱歉!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 20:04:03 | 显示全部楼层
指出你的一个错误吧 你似乎480bit乘都是循环展开的 但我们需要的是可以处理任何输入的通用函数 不要说循环展开等于通用的比较结果 考虑展开情况下你可以充分的隔离依赖指令 使指令延迟的副作用最小 而且还能动用最大化的mm寄存器 所以很多优化在循环情况下是不能使用的 所以必须使用循环版本 最简单的,乘法延迟>=6,要在6个时钟后才能用 所以循环情况下,最小的每双字的消耗就是6 而展开情况下,可充分利用每时钟能发送一条乘法的优势 使乘法延迟的损耗最小化 循环时的时间你算过么? 我想你的P4 2.6应该在590ms左右
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 20:35:30 | 显示全部楼层
遇到麻烦了!!! 将yaos写的代码添加到测试环境,这样一来,总共被测函数达到7个,奇怪的是,但打开这些函数的其中几个,会对基为 $2^30 $SSE2版本的性能造成影响。 比如 UInt480x480_MMX 和 UInt480x480_yaos(yaos写的代码,稍加封装)测试其中的一个或者几个,竟然对 UInt480x480_base30_MMX 性能造成明些的影响。 UInt480x480_MMX UInt480x480_yaos UInt480x480_base30_MMX 用时间 关闭(不测试) 关闭(不测试) 394ms 关闭(不测试) 打开(测试) 394ms 打开(测试) 关闭(不测试) 396ms 打开(测试) 打开(测试) 575ms 另外,打开或者 UInt480x480_ALU2 或 UInt480x480_ALU 也会对最后2个基为$2^30$ SSE2版本造成影响。测试发现,关闭UInt480x480_ALU2 会造成 基为 $2^30 $SSE2版本变慢。 还有一点,我的完全 使用循环展开 的版本(基同为为$2^32$) 竟比 yaos的慢,我也不能给出合理的解释。 下面为在PIV2.6G下的测试结果. 关闭最后3个基为 2^30 的函数后的测试结果。 Test function: UInt480x480_ALU(..) 1000000 times... Elapsed time: 1287.924 ms Test function: UInt480x480_ALU2(..) 1000000 times... Elapsed time: 1244.897 ms Test function: UInt480x480_MMX(..) 1000000 times... Elapsed time: 996.383 ms Test function: UInt480x480_yaos(..) 1000000 times... Elapsed time: 752.210 ms 关闭最后UInt480x480_MMX和 UInt480x480_yaos 后的测试结果。 Test function: UInt480x480_ALU(..) 1000000 times... Elapsed time: 1282.592 ms Test function: UInt480x480_ALU2(..) 1000000 times... Elapsed time: 1243.553 ms Test function: UInt480x480_base30_ALU(..) 1000000 times... Elapsed time: 1252.155 ms Test function: UInt480x480_base30_MMX(..) 1000000 times... Elapsed time: 397.942 ms Test function: UInt480x480_base30_SSE2(..) 1000000 times... Elapsed time: 533.329 ms 代码暂缓公布,回去写几个通用版本,可以在参数中指定被乘数和乘数的长度。将使用部分循环展开技术。接口类似为: void Mul_func(DWORD *result,const DWORD *left, const DWORD *right, DWORD sLeft,DWORD sRight);
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 20:46:00 | 显示全部楼层
呵呵 我说快也快不了多少么 循环版是一个乘两个加 极端有规律的 你线程最大化优先级了么? ====================== 部分循环展开 就是一次乘4个吧 要处理非4倍数的部分
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-9 20:51:00 | 显示全部楼层
原帖由 无心人 于 2008-4-9 20:46 发表 部分循环展开 就是一次乘4个吧 要处理非4倍数的部分
回楼上,不是的,因为我使用的循环结构和你的不同,所以不能使用 4路循环展开。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-9 20:56:56 | 显示全部楼层
那我想做4路展开 如果你的代码时间不能达到我时间的80%以内 你的代码是很没效率的, 因为加法是肯定慢的 加法不可能快于2^32的基
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-10 13:08:52 | 显示全部楼层
33# 楼提到,“还有一点,我的完全 使用循环展开 的版本(基同为为232) 竟比 yaos的慢,我也不能给出合理的解释。” 现在终于找到原因了,我写的那个UInt480x480_MMX有冗余指令,稍作优化后,速度迅速提升,从之前的989.54ms提升到 481.540 ms,竟快了1倍多,提速太多了。我无法给出合理的解释。 将现在的基为$2^32$的函数 Int480x480_MMX 和 基为$2^30$的函数UInt480x480_base30_MMX做一个对比,则后者比前者快了25%。 我也写了一个可类似yaos的非循环展开的版本,速度比yaos的那个版本快了8%左右。可参考楼下给出的源代码。 这个数据(提速到125%)可比以前的250%更合理一点,但单从指令条数分析,速度应该提升到200%以上才对。但MMX指令的版本怪就怪在 速度的变化无法琢磨,无法用理论的方法给出合理的解释。无论如何,让我们见识了一个可以大幅提高大数乘法运行速度的新途径,提高的幅度太大了,太出人所料了。 6个版本的速度对比。 Test function: UInt480x480_ALU(..) 1000000 times... Elapsed time: 1244.770 ms Test function: UInt480x480_ALU2(..) 1000000 times... Elapsed time: 1216.745 ms Test function: UInt480x480_MMX(..) 1000000 times... Elapsed time: 481.540 ms Test function: UInt480x480_base30_ALU(..) 1000000 times... Elapsed time: 1222.405 ms Test function: UInt480x480_base30_MMX(..) 1000000 times... Elapsed time: 385.115 ms Test function: UInt480x480_base30_SSE2(..) 1000000 times... Elapsed time: 527.090 ms 5个基同为$2^32$的版本的速度对比: Test function: UInt480x480_ALU(..) 1000000 times... Elapsed time: 1248.710 ms Test function: UInt480x480_ALU2(..) 1000000 times... Elapsed time: 1219.125 ms Test function: UInt480x480_MMX(..) 1000000 times... Elapsed time: 482.380 ms Test function: UInt480x480_MMX2(..) 1000000 times... Elapsed time: 693.360 ms Test function: UInt480x480_yaos(..) 1000000 times... Elapsed time: 725.490 ms
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-4-10 13:11:17 | 显示全部楼层
本压缩包包含2个工程文件,geneCodes.dsp 和binMulTest.dsp。前者用来生成后者的部分原代码。 运行geneCodes.exe,将生成3个.c文件(本来可生成6个文件的,在上载该压缩包前作了处理,屏蔽了3个基为$2^32$3个函数的输出) 使用后者之前,先运行geneCodes.exe,生成后者所需的3个文件.然后可打开binMulTest.dsp 并编译即可生成用来一个名为 binMulTest.exe,该程序可计算2个480bit的乘积,使用了几种不同的算法,给给出他们的速度.需要注意的是,binMulTest的源代码中并没有包含基为$2^30$的几个函数,而事先编译好的binMulTest.exe 则包含了所有6个函数的速度测试。

binMulTest_tmp.rar

48.89 KB, 阅读权限: 20, 下载次数: 6, 下载积分: 金币 -1 枚, 经验 1 点, 下载 1 次

售价: 2 枚金币  [记录]

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-10 15:56:07 | 显示全部楼层
我这里差别也是不大 ALU 1696 ALU2 1668 MMX 646 30_MMX 549 30_SSE2 777
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-4-10 20:15:26 | 显示全部楼层
写了一个四路并行乘法 有时间调试下看效果如何? mov esi, [left] mov edi, [right] mov ebx, [result] mov ecx, [sLeft] mov edx, [sRight] cmp ecx, edx jbe noExchange xchg esi, [right] xchg edi, [left] xchg ecx, [sRight] xchg edx, [sLeft] noExchange: test ecx, -1 je exit1 //长度0 test edx, -1 je exit1 //长度0 mov ecx, 0 pxor mm0, mm0 movd mm7, [esi] add esi, 4 mov eax, edx shr edx, 2 je firstLoop2 //不足4个 firstLoop1: movd mm1, [edi] pmuludq mm1, mm7 movd mm2, [edi+4] pmuludq mm2, mm7 movd mm3, [edi+8] pmuludq mm3, mm7 movd mm4, [edi+12] pmuludq mm4, mm7 add edi, 16 paddq mm0, mm1 movd [ebx], mm0 psrlq mm0, 32 paddq mm0, mm2 movd [ebx+4], mm0 psrlq mm0, 32 paddq mm0, mm3 movd [ebx+8], mm0 psrlq mm0, 32 paddq mm0, mm4 movd [ebx+12], mm0 psrlq mm0, 32 add ebx, 16 sub edx, 1 jne firstLoop1 firstLoop2: mov edx, eax and edx, 3 je exitFirstLoop firstLoop3: movd mm1, [edi] pmuludq mm1, mm7 add edi, 4 paddq mm0, mm1 movd [ebx], mm0 psrlq mm0, 32 add ebx, 4 sub edx, 1 jne firstLoop3 exitFirstLoop: movd [ebx], mm0 add ecx, 1 cmp ecx, [sLeft] jae exit1 //左操作数就一个双字 add esi, 4 outLoop1: movd mm7, [esi] mov ebx, [result] lea ebx, [ebx+ecx*4] mov edi, [right] mov edx, [sRight] pxor mm0, mm0 mov eax, edx shr edx, 2 je innerLoop2 innerLoop1: movd mm1, [edi] pmuludq mm1, mm7 movd mm5, [ebx] movd mm2, [edi+4] pmuludq mm2, mm7 movd mm6, [ebx+4] movd mm3, [edi+8] pmuludq mm3, mm7 movd mm4, [edi+12] pmuludq mm4, mm7 add edi, 16 paddq mm0, mm1 paddq mm0, mm5 movd [ebx], mm0 movd mm5, [ebx+8] psrlq mm0, 32 paddq mm0, mm2 paddq mm0, mm6 movd [ebx+4], mm0 movd mm6, [ebx+12] psrlq mm0, 32 paddq mm0, mm3 paddq mm0, mm5 movd [ebx+8], mm0 psrlq mm0, 32 paddq mm0, mm4 paddq mm0, mm6 movd [ebx+12], mm0 psrlq mm0, 32 add ebx, 16 sub edx, 1 jne innertLoop1 innerLoop2: mov edx, eax and edx, 3 je outLoop2 innerLoop3: movd mm1, [edi] pmuludq mm1, mm7 movd mm5, [ebx] add edi, 4 paddq mm0, mm1 paddq mm0, mm5 movd [ebx], mm0 psrlq mm0, 32 add ebx, 4 sub edx, 1 jne firstLoop2 outLoop2: movd [ebx], mm0 add ecx, 1 cmp ecx, [sLeft] jb outLoop1 exit1:
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-12-22 11:06 , Processed in 0.028019 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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