Параллельное выполнение с многопроцессорной обработкой. Пул медленнее последовательного при обработке растровых данных.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Параллельное выполнение с многопроцессорной обработкой. Пул медленнее последовательного при обработке растровых данных.

Сообщение Anonymous »

Я работаю над программой Python, которая обрабатывает растровые данные с использованием rasterio и параллелизма с multiprocessing.Pool. Цель состоит в том, чтобы извлечь несколько фрагментов из большой растровой мозаики на основе положений частиц. Вот код, который я использую:

Код: Выделить всё

import rasterio
import multiprocessing
import heapq
import random
import time
from functools import lru_cache
from rasterio.windows import Window

NUMBER_OF_WORKERS = 4
CROP_PX_SIZE = 384
PARTICLES_NUMBER = 1000
MOSAIC_PATH = 'path_to_mosaic.tif'

def get_crops(particles_positions):
crops_by_particles = []
with multiprocessing.Pool(NUMBER_OF_WORKERS) as pool:
pool.starmap(worker, [(particle_position, crops_by_particles) for particle_position in particles_positions])
return list(crops_by_particles)

def worker(particle_position, crops_by_particles):
crop = get_map_crop_for_particle_position(particle_position)
heapq.heappush(crops_by_particles, (particle_position, crop))

def get_map_crop_for_particle_position(particle_position):
mosaic = get_mosaic()

row_off_px, col_off_px = rasterio.transform.rowcol(mosaic.transform, particle_position[0], particle_position[1])
row_off_px = row_off_px - (CROP_PX_SIZE // 2)
col_off_px = col_off_px - (CROP_PX_SIZE // 2)
crop_window = Window(col_off_px, row_off_px, CROP_PX_SIZE, CROP_PX_SIZE)
return mosaic.read(window=crop_window)

@lru_cache()
def get_mosaic():
return rasterio.open(MOSAIC_PATH)

if __name__ == "__main__":
lat = -3.7
lon = 40.2
error = 0.001
particles = [(random.gauss(lat, error), random.gauss(lon, error)) for _ in range(PARTICLES_NUMBER)]
start_time = time.time()
get_crops(particles)
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
print(f"Execution time: {execution_time_ms:.2f} ms")
При параллельном выполнении программа работает медленнее, чем при последовательном выполнении. Даже когда я запускаю его параллельно, результат намного хуже при 8 потоках, чем при 4. Также при 4 он хуже, чем при 2 и т. д. Такое поведение неожиданно, поскольку параллелизм должен улучшить производительность для независимых задач.
  • После некоторой отладки я подозреваю, что проблема может быть связана с тем,
    как обрабатывается rasterio.open:

    Я использую @lru_cache в get_mosaic(), чтобы избежать повторного открытия мозаики несколько раз, но я подозреваю, что это не очень хорошо работает с многопроцессорной обработкой.
Приводит ли размещение rasterio.open к снижению эффективности? Насколько я понимаю, его следует вызывать внутри каждого работника, чтобы обеспечить независимые дескрипторы файлов.
Является ли использование общих объектов (crops_by_particles) в сочетании с heapq проблематичным? Должен ли я использовать другой механизм для сбора результатов?
Существуют ли какие-либо рекомендации по использованию многопроцессорной обработки с несериализуемыми объектами, такими как rasterio.DatasetReader?
Любые советы по выявлению и устранению узких мест был бы очень признателен! Заранее спасибо.

Подробнее здесь: https://stackoverflow.com/questions/792 ... -raster-da
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»