矩阵乘法效率比较
1. 矩阵乘法
在很多的科学计算中,矩阵运算是十分基础而重要的计算步骤,有时甚至因为大量迭代运算或大规模矩阵计算而带来十分巨大的资源开销和时间消耗。spark作为分布式计算的框架,在解决大规模计算时有得天独厚的优势,而作为spark中主流的科学计算库mlib,其中的矩阵运算是我们经常会使用到的。之前的博文详细介绍了本地存储的两种矩阵形式——稠密矩阵DenseMatrix和稀疏矩阵SparseMatrix,而mlib也提供了多种分布式矩阵存储的方式和计算方法,这个将在之后的博文中一一探究,本文将着重探寻本地矩阵乘法的效率问题,也同样是分布式矩阵计算的效率基础。
矩阵乘法相信大家都已经十分熟悉了,通过行与列的对应相乘累加,获得结果矩阵中的一个个元素:
而当相乘的两个矩阵中有一个换成了稀疏矩阵,则矩阵乘法所需要计算的元素数量仅为稀疏矩阵的元素数量,通过稀疏矩阵所存储的非0元素的索引,可以跳过0元素的乘法运算,减少不必要的计算开销。
所以从理论上说,利用稀疏矩阵进行乘法计算,则计算所需时间随含0元素比率增加而减少,所以本文正是要讨论在spark的mlib中,矩阵乘法运算利用哪种矩阵存储形式更快。
2. 效率比较
为了使得矩阵乘法运算的时间差异表征不同运算方式带来的时间差异,计算矩阵所需的CPU时间必须远大于其它外界软硬件因素导致的计时误差,故本测试选用100x100含有10000个元素的矩阵进行测试。再考虑到不同计算方法下,尽可能保证计算的公平性和稳定性,故计算所用矩阵的非0值采用固定方法生成,生成测试矩阵的代码如下:
val numSize: Int = 10000 //设置矩阵元素总数
val rowSize: Int = 100 //设置矩阵行数
val colSize: Int = numSize / rowSize //计算矩阵列数
val zerosRate: Int = 50 //设置B矩阵产生0元素的概率(0-100)
val array1 = new Array[Double](numSize)
val array2 = new Array[Double](numSize)
for (i <- 1 to numSize) {
array1(i-1) = i //按顺序从小到大填充A矩阵
if (Random.nextInt(100) < zerosRate) {