цикл для Python замедляет каждую итерацию - PullRequest
3 голосов
/ 01 мая 2011

Я пытаюсь оптимизировать некоторый код на 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)))

Я хотел бы понять, почему программа начинает работать быстро во время первых итераций, а затем замедляется при дальнейшей итерации?Я знаю, что вопрос может быть немного наивным, но я действительно хочу иметь более четкое представление о том, что происходит, прежде чем пытаться что-то еще.Я уже реализовал свою функцию в Фортране (оставляя в пределах области Фортрана любую для циклов) и использовал 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 раза медленнее, чем первая версия (важно отметить, что я использовал MATMUL () в реализации на Fortran).Я некоторое время гуглял и считаю, что это «замедление» связано с пропускной способностью памяти, выделением памяти или кэшированием, учитывая большие наборы данных, но я не очень уверен в том, что на самом деле происходит и какМогу ли я улучшить производительность.Я запустил код на небольшом Intel Atom, 2 ГБ оперативной памяти и 4-ядерном Intel Xeon, с 8 ГБ (конечно, с соответствующим масштабированным набором данных), и поведение «замедления» одинаково.

Мне просто нужно понять, почему происходит это «замедление»?Будет ли это полезно, если я реализую функцию в C?или попытаться реализовать это для запуска на GPU?Есть еще идеи как его улучшить?Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 01 мая 2011

С риском констатировать очевидное, число выполнений внутреннего цикла будет расти каждый раз, когда вы завершаете выполнение внешнего цикла.Когда i равен 0, внутренний цикл будет выполняться только один раз, но когда i равен 100, он будет выполнен 101 разМожет ли это объяснить ваши наблюдения или вы имеете в виду, что каждое выполнение самого внутреннего цикла со временем замедляется?

2 голосов
/ 01 мая 2011

Количество выполнений внутреннего цикла for зависит от значения i, индекса внешнего цикла for.Так как вы отображаете отладку каждый раз, когда завершается внутренний цикл, он отображается все реже по мере увеличения i.(Обратите внимание, что процент регулярно увеличивается, однако.)

...