Код: Выделить всё
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")
- После некоторой отладки я подозреваю, что проблема может быть связана с тем,
как обрабатывается rasterio.open:
Я использую @lru_cache в get_mosaic(), чтобы избежать повторного открытия мозаики несколько раз, но я подозреваю, что это не очень хорошо работает с многопроцессорной обработкой.
Является ли использование общих объектов (crops_by_particles) в сочетании с heapq проблематичным? Должен ли я использовать другой механизм для сбора результатов?
Существуют ли какие-либо рекомендации по использованию многопроцессорной обработки с несериализуемыми объектами, такими как rasterio.DatasetReader?
Любые советы по выявлению и устранению узких мест был бы очень признателен! Заранее спасибо.
Подробнее здесь: https://stackoverflow.com/questions/792 ... -raster-da