找回密码
 欢迎注册
查看: 26215|回复: 22

[擂台] 寻求最快速的矩阵乘实现

[复制链接]
发表于 2010-10-25 23:56:54 | 显示全部楼层 |阅读模式

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

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

×
目标:
        时间最短是王道!
规则:

1.输入精度:
        double双精度型(64位),即使用matlab默认的数据精度。
2.输入值:
        A=rand(n,m),B=rand(m,p)  生成的0~1的两个随机数矩阵(矩阵行列通常在1000位左右),依然遵循matlab的rand函数
        (线性同余伪随机数发生器,可自行实现),计算C(n,p)=A(n,m)*B(m,p)。
3.时间测试:
        从rand开始,到矩阵乘计算结束。

附:
        不包括GUI或CUI的显示时间(此显示仅仅确认结果的正确性)。
        空间开销不计。指令集不限,程序语言不限,运行平台不限。Good luck!!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-26 10:14:21 | 显示全部楼层
目标:
...
3.时间测试:
        从rand开始,到矩阵乘计算结束 ...
G-Spider 发表于 2010-10-25 23:56


我觉得应是“从rand开始,到矩阵乘计算结束”,因为rand算法也会有所不同的,虽然影响不大。

我很少涉及浮点运算,也没针对通用矩阵进行优化的经验,所以静观高手表演。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-10-26 14:03:02 | 显示全部楼层
2# gxqcn
郭兄这么说也有道理,对于时间的测试我在写的时候就有所顾虑,矩阵乘核涉及读取数据,计算,返回结果。读取数据的效率会严重影响计算效率,未对齐的数据可能会浪费更多读取时间,我猜想matlab在定义一个大矩阵的时候不会傻瓜似的顺序罗列...我加上rand的时间是希望在数据的预处理上动些手脚,这样可能使矩阵乘核工作的更加有效。我会征求大家意见和建议。
期待高人....
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-26 19:13:04 | 显示全部楼层
1# G-Spider
感谢楼主专门出贴讨论这个问题!
到底是高手,比我在这个帖子21#的问题2总结的更到位:http://bbs.emath.ac.cn/thread-2709-1-1.html
一直期待国内的高手亮相,老听人说matlab的矩阵算法是最牛的,一直未全信。

做两个测试吧?也不麻烦。

1、从rand后开始,到矩阵乘计算结束。
2、从rand前开始,到矩阵乘计算结束。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-26 19:43:17 | 显示全部楼层
我先献丑,垫个底,助助兴。

1、从rand后开始,到矩阵乘计算结束。

Forcal代码:
  1. !using["math","sys"];
  2. (:a,b,k,t0)=
  3. oo{
  4.   a=rand[1000,1000], b=rand[1000,1000],
  5.   t0=clock(),
  6.   k=a*b  //矩阵乘
  7. },
  8. [clock()-t0]/1000;
复制代码
耗时约2.219秒。

2、从rand前开始,到矩阵乘计算结束。

Forcal代码:
  1. !using["math","sys"];
  2. (:a,b,k,t0)=
  3. t0=clock(),
  4. oo{
  5.   a=rand[1000,1000], b=rand[1000,1000],
  6.   k=a*b  //矩阵乘
  7. },
  8. [clock()-t0]/1000;
复制代码
耗时约2.328秒。

我的电脑:Intel Core 2 Duo T5500 1.66G 1G内存。
只有一个核在运行(多核不会弄)。
可下载OpenFC(绿色免安装,2M)演示以上代码:http://www.forcal.net/xiazai/forcal9/openfc32w.rar
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-29 13:28:30 | 显示全部楼层
可惜我的显卡的GPU不支持double计算,要不我写一个调用CUDA矩阵库的测试程序。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-10-29 14:24:08 | 显示全部楼层
6# liangbch
那就先用单精度型的吧(32位),实际上我暂时先写的float版本 ,雏形已经有了,使用SSE2系统指令集,
未对B矩阵转置,且A,B的列是4的整数倍的情形下......昨天主要完成了这个模块....

随机函数使用了c中的rand()改造版本,在种子相同的情形下,得到相同的随机数。
随机参数:
2.jpg
跟踪c版的rand函数:
rand.jpg
;.......................................................

A(1024,1024)*B(1024,1024) 单精度乘法,A,B种子分别为1和2(单线程在core 2测试已确保结果正确性),在320ms左右完成,预计加上B的转置和对非4整数倍的处理之后,在500ms内计算完成
3.jpg
直接把部分结果拷到文件中了
4.jpg
当然死算每一个乘积,几乎已到了尽头,虽然用到了矢量.我很不甘心,恐怕这种方式不可能超过matlab的矩阵乘。

刚才看到一篇斯特拉森矩阵乘法的文章我颇有顾虑:
数据从rand a,b到转成0~1之间的浮点,整个过程也只用了15ms左右
接着是计算a*b
乘法的代价过大,只有提供一种高效的算法来减少乘法的运算次数才能有质的飞跃....酝酿中.....
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-29 14:33:11 | 显示全部楼层
矩阵乘法我只知道那个n^log(2,7)的分治方法,难道有类似fft的变换么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-10-29 16:21:23 | 显示全部楼层
乘法的代价过大,只有提供一种高效的算法来减少乘法的运算次数才能有质的飞跃....酝酿中..... G-Spider 发表于 2010-10-29 14:24

我在5#的矩阵乘算法仅使用C/C++实现,如果你也仅使用C/C++实现,能达到或超过我这个速度,那我就帮不上忙了。

否则,使用我这个雕虫小技或许会使速度有更大的提高。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-10-29 20:14:33 | 显示全部楼层
9# forcal
8# litaoye
看来要使用一些高级的算法才能降低时间复杂度.
看一下乘法的计算次数:
普通:0(n^3)......1024^3=1 073 741 824次乘运算
Strassen分治:0(n^2.81)............1024^2.81=  287 701 988次算运算
Don Coppersmith and Shmuel Wmograd改进:0(n^2.367).........1024^2.367= 13 346 887次算运算
........
当然在实现上的难度会越来越大............
最新的矩阵乘算法动态,可参考:
Fast and stable matrix multiplication
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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