我正在尝试优化一些python代码(加快一些矩阵操作),我的代码是类似于这一个(我的真实数据集也类似于'gps'),
import numpy as np
gps = [np.random.rand(50,50) for i in xrange(1000)]
ips = np.zeros( (len(gps),len(gps)), dtype='float32')
for i in xrange(len(gps)):
for j in xrange(0,i+1):
ips[i,j]= f.innerProd(gps[i],gps[j])
ips[j,i]= ips[i,j]
print "Inner product matrix: %3.0f %% done (%d of %d)"%
(((i+1)**2.)/(len(gps)**2.)*100, i, len(gps))
def innerProd(mat1,mat2):
return float(np.sum(np.dot(np.dot(mat1,mat2),mat1)))
我想要理解的是,为什么程序在第一次迭代时开始快速运行,然后在进一步迭代时减慢速度?我知道这个问题可能有点天真,但在我尝试其他任何事情之前,我真的想更清楚地了解正在发生的事情。我已经在Fortran中实现了我的函数(在Fortran领域中留下了任何for循环),并使用f2py创建了一个动态库来从python调用该函数,这将是python中的新代码。
import numpy as np
import myfortranInnProd as fip
gps = [np.random.rand(50,50) for i in xrange(1000)]
ips = np.zeros( (len(gps),len(gps)), dtype='float32')
ips = fip.innerProd(gps)
不幸的是,我只发现(令人惊讶的)我的Fortran -python版本比第一个版本慢1.5 ~ 2倍(重要的是要提到我在Fortran实现上使用了MATMUL())。我已经在谷歌上搜索了一段时间,我相信这种"变慢"与内存带宽、内存分配或缓存有关,考虑到大型数据集,但我不太确定背后到底发生了什么,以及我如何提高性能。我在一个小的intel atom, 2GB ram和一个4核intel xeon上运行代码,8GB(当然有相应的缩放数据集)和"减速"行为是相同的。
我只是需要明白为什么会发生这种"慢下来"?如果我用C实现这个函数会有什么好处吗?或者尝试在GPU上运行它?还有其他改进方法吗?提前感谢
冒着显而易见的风险,每次完成外部循环的执行,内部循环的执行次数都会增加。当i
为0时,内循环只执行一次,而当i
为100时,内循环将执行101次。这是否可以解释您的观察结果,或者您的意思是每次执行内循环本身都随着时间的推移而变得越来越慢?
内部for
循环的执行次数取决于外部for
循环的索引i
的值。由于每次内部循环结束时都显示调试,因此随着i
的增长,它的显示次数越来越少。(请注意,百分比有规律地增加。)