Скорость БПФ на некубических сетках
Мне нужно многократно использовать преобразование Фурье / обратное преобразование Фурье 3d-функции, чтобы решить дифференциальное уравнение. Что-то вроде:
import pyfftw.interfaces.numpy_fft as fftw
for i in range(largeNumber):
fFS = fftw.rfftn(f)
# Do stuff
f = fftw.irfftn(fFS)
Форма f очень не кубическая. Есть ли разница в производительности в зависимости от порядка размеров, например (512, 32, 128) и (512, 128, 32) и т. Д.?
Я ищу любые доступные ускорения. Я уже пытался играть с мудростью. Я думал, что это может быть быстрее, если наибольшее измерение будет последним (например, 32, 128, 512), так что fFS.shape = (32, 128, 257), но это не так.
1 ответ
Если вы действительно хотите выжать всю производительность, какую только можете, используйте объект FFTW напрямую (проще всего получить через pyfftw.builders
). Таким образом, вы получаете тщательный контроль над тем, какие именно копии происходят, и выполняется ли нормализация в обратном порядке.
Ваш код как есть, скорее всего, выиграет от использования кэша (включается путем вызова pyfftw.interfaces.cache.enable()
), что минимизирует время установки для общего и безопасного случая, но не устраняет его.
Что касается лучшего расположения размеров, вам придется пососать его и посмотреть. Попробуйте все варианты и посмотрите, что быстрее (с timeit
). Убедитесь, что при выполнении тестов вы фактически используете данные, упорядоченные в памяти, как ожидалось, а не просто просматриваете один и тот же массив в памяти (который pyfftw
может хорошо работать без копии - хотя для такого рода вещей есть параметры настройки).
FFTW
пробует множество разных опций (разные алгоритмы в разных представлениях FFT) и выбирает самые быстрые, так что вы получите неочевидные реализации, которые могут измениться для разных наборов данных, которые внешне очень похожи.
Общие советы:
- Включите многопоточность для максимальной производительности (установите
threads=N
где уместно). - Убедитесь, что ваши массивы соответствующим образом выровнены по байтам - это оказывает меньшее влияние, чем раньше на современном оборудовании, но, вероятно, будет иметь значение (особенно если все ваши более высокие размеры имеют фактор байтового выравнивания).
- Прочитайте учебник и API-документы.