Python для петли медленнее каждую итерацию
-
27-10-2019 - |
Вопрос
Я пытаюсь оптимизировать код 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 Any для цикла) и использовал 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 раза медленнее, чем первая версия (важно упомянуть, что я использовал Matmul () в реализации Fortran). Я некоторое время гуглил, и я считаю, что это «замедление» имеет какое -то отношение к пропускной способности памяти, распределению памяти или кэшированию, учитывая большие наборы данных, но я не очень уверен в том, что на самом деле происходит и как Могу ли я улучшить производительность. Я запустил код как на небольшом атоме Intel, 2 ГБ оперативной памяти, так и 4 -ядра Intel Xeon, с 8 ГБ (конечно, с соответственно масштабированным набором данных), а поведение «замедленного» - одинаковое.
Мне просто нужно понять, почему происходит это «замедление»? Будет ли это хорошо, если я реализую функцию в C? Или попытаться реализовать его для запуска на графическом процессоре? Есть ли другие идеи, как это улучшить? заранее спасибо
Решение
С риском заявления о очевидном количестве выполнения внутреннего цикла будет расти каждый раз, когда вы выполняете выполнение внешнего цикла. Когда i
равно 0, внутренний цикл будет выполнен только один раз, но когда i
100, он будет выполнен 101 раз. Может ли это объяснить ваши наблюдения, или вы имеете в виду, что каждое выполнение самого внутреннего цикла со временем становится медленнее?
Другие советы
Количество казней внутреннего for
петля зависит от значения i
, индекс внешнего for
петля. Поскольку вы отображаете отладку каждый раз, когда внутренний цикл заканчивается, он отображается реже и реже, как i
растет. (Обратите внимание, что процент регулярно увеличивается.) Однако.)