使用MKL优化的numpy.dot()与3d数组

时间:2015-01-31 22:44:05

标签: python arrays multithreading numpy intel-mkl

我一直在尝试优化我的代码一段时间,并且只是意识到每当我尝试将numpy.dot与3维或更多维数组一起使用时,会有巨大的性能损失。

例如,这段代码:

def ti():
  r = random.rand(8,256,32**2)
  p = random.rand(32**2,256)
  o = empty((8,256,256))
  for k in xrange(100):
    dot(r,p,o)

比以下转换慢50倍(在8核macbook pro上):

def ti2():
  r = random.rand(8*256,32**2)
  p = random.rand(32**2,256)
  o = empty((8*256,256))
  for k in xrange(100):
    dot(r,p,o)

事实证明,第一个代码块没有使用多个内核,这让我想知道它是否正在使用MKL。

有没有办法强制第一个代码块是多线程的并使用MKL而不将其明确地转换为第二个代码块?实际上,我正在使用的数组是4d和5d,我想避免折叠所有的开始维度(我还在数组上执行其他操作,比如在原始4d数组的第二维上取总和如果我将整个数组只分成2个维度,这将变得更加复杂。或者,为了使代码的其余部分可读,通过将数组从4d重新塑造为2d,然后在该步骤之后返回到4d,我将遭受多大的性能损失?或者是否有更有效的方法在两个形状之间转换数据?

更新: 我还尝试使用简单的嵌套for循环迭代第一维,它似乎工作得相对较好,但我是cython的新手,但还没能将它转换为cython。专门的cython功能会增加很多性能吗?

2 个答案:

答案 0 :(得分:1)

没有内置的方式。在numpy bug跟踪器上有一个open issue,在邮件列表上有一个discussion。这两个都是相当陈旧的,所以看起来这几年没有取得进展。

我确实发现this blog post链接到一个名为fastdot的小型图书馆,声称可以更快地完成高维网格产品,但我还没有亲自使用它,所以我可以&#39 ; t确定它有多好(或者是否有效)。

答案 1 :(得分:0)

您可以尝试np.tensordot,因为它会在引擎盖下进行重塑和2D点。

o = np.tensordot(r, p, [[-1], [-2]])

至于性能损失,似乎可以在不特定情况下进行重新整形(rp都是C连续的)并且在这种情况下应该几乎没有影响在表现上。遗憾的是它不支持输出参数,但如果你真的需要它,你可以修改source code