每次迭代时python for循环都会变慢

时间:2011-05-01 01:45:34

标签: python for-loop performance memory-bandwidth

我正在尝试优化一些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创建一个动态lib来从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())。我一直在谷歌搜索一段时间,我相信这种“减速”与内存带宽,内存分配或缓存有关,考虑到大型数据集,但我不太确定背后真正发生的事情以及如何我可以改善表现吗?我已经在小型英特尔原子,2GB内存和4核英特尔至强处理器上运行代码,8GB(当然还有相应的缩放数据集)并且“减速”行为是相同的。

我只需要理解为什么这种'减速'会发生?如果我在C中实现该功能,它会有用吗?或尝试实现它在GPU上运行?还有其他想法如何改进吗?提前致谢

2 个答案:

答案 0 :(得分:4)

冒着明显的风险,每次完成外循环的执行时,内循环的执行次数会增加。当i为0时,内循环仅执行一次,但当i为100时,将执行101次。这可以解释你的观察结果,还是你的意思是内循环本身的每次执行都会随着时间的推移变慢?

答案 1 :(得分:2)

内部for循环的执行次数取决于i的值,即外部for循环的索引。由于每次内部循环完成时都会显示调试,因此随着i的增长,它会越来越少地显示出来。 (请注意,百分比会定期增加。)