Я хотел бы рассчитать спектральные нормы N 8х8 эрмитовых матриц с N быть близко к 1Е6. В качестве примера возьмем эти 1 миллион случайных комплексных матриц 8х8:Вычисление спектральных норм ~ 1м эрмитовых матриц: `numpy.linalg.norm` слишком медленно
import numpy as np
array = np.random.rand(8,8,1e6) + 1j*np.random.rand(8,8,1e6)
В настоящее время он занимает у меня почти 10 секунд с помощью numpy.linalg.norm
:
np.linalg.norm(array, ord=2, axis=(0,1))
Я попытался с помощью кода Cython ниже, но это дало мне только незначительное улучшение производительности:
import numpy as np
cimport numpy as np
cimport cython
np.import_array()
DTYPE = np.complex64
@cython.boundscheck(False)
@cython.wraparound(False)
def function(np.ndarray[np.complex64_t, ndim=3] Array):
assert Array.dtype == DTYPE
cdef int shape0 = Array.shape[2]
cdef np.ndarray[np.float32_t, ndim=1] normarray = np.zeros(shape0, dtype=np.float32)
normarray = np.linalg.norm(Array, ord=2, axis=(0, 1))
return normarray
Я также попытался Numba и некоторые другие SciPy функции (например, scipy.linalg.svdvals
) вычислить т сингулярные значения этих матриц. Все еще слишком медленно.
Невозможно сделать это быстрее? Является ли numpy уже оптимизированным до такой степени, что увеличение скорости невозможно при использовании Cython или numba? Или мой код очень неэффективен, и я делаю что-то принципиально неправильное?
Я заметил, что только два из моих ядер процессора используются на 100% при выполнении вычислений. Имея это в виду, я смотрел на эти предыдущие вопросы StackOverflow:
Why does multiprocessing use only a single core after I import numpy?
multithreaded blas in python/numpy (не помогло)
и несколько других, но, к сожалению, у меня все еще нет решения.
Я подумал о том, чтобы разделить мой массив на более мелкие куски и обработать их параллельно (возможно, на графическом процессоре с использованием CUDA). Есть ли способ в numpy/Python для этого? Я еще не знаю, где узкое место в моем коде, то есть ли это процессор или память, или, возможно, что-то другое.
Вы не увидите каких-либо преимуществ в производительности от Cython или numba, если вы просто используете их для вызова функции numpy. Cython и numba не знают о внутренней работе numpy и не могут ничего сделать для оптимизации функций numpy - вам нужно будет написать свои собственные низкоуровневые циклы над массивом для вычисления нормы. –
Этот расчет линейно вычисляется с помощью 'N'. Простое создание массива занимает 1/4 времени, когда принимает норма. И на моей относительно старой машине 1e6 слишком велик, чтобы даже генерировать массив. Таким образом, большая часть проблемы скорости - это размер сдвига данных. – hpaulj
Спасибо за ответы, я думаю, я не могу бить numpy, кроме переписывания всего на петле очень низкого уровня. – BPresent