Я пытаюсь сделать следующий код параллельным: feret_diamater.py
Когда я вызываю функцию get_min_max_feret_from_labelim() с помеченным изображением (например, массив 1000x1000, метки — это числа от 0 до 1100), она вызывает функцию get_min_max_feret_from_mask() для каждой метки. В результате get_min_max_feret_from_labelim() возвращает список из 1101 элемента. Работает нормально, но в случае большого изображения и множества меток это занимает очень много времени, поэтому я хочу вызвать get_min_max_feret_from_mask() с помощью многопроцессорного пула.
В исходном коде используется это:
for label in labels:
results[label] = get_min_max_feret_from_mask(label_im == label)
return results
И я хочу заменить эту часть. Я попробовал это после добавления «ncores» в список параметров:
with Pool(ncores) as p:
for label in labels:
results[label] = p.map(get_min_max_feret_from_mask, label_im == label)
return results
Но это не работает. Как я могу решить эту проблему? Спасибо.
Ты можешь написать:
with Pool(ncores) as p:
return p.map(get_min_max_feret_from_mask, labels)
Pool.map
принимает итерируемый объект (список или кортеж и т. д.) непосредственно в качестве второго параметра, дополнительный цикл не требуется:
https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.map
Map ожидает список аргументов и возвращает список результатов:
with Pool(ncores) as p:
result_list = p.map(get_min_max_feret_from_mask, [label_im == label for label in labels])
Возвращенный список будет соответствовать порядку списка аргументов, то есть первый результат будет результатом для первой метки и так далее.
Другой вариант — использовать apply_async
для планирования задач без блокировки, это немедленно возвращает объект AsyncResult, позволяющий получить результаты позже. Этот позволяет сохранить исходную структуру:
with Pool(ncores) as p:
for label in labels:
async_results[label] = p.apply_async(get_min_max_feret_from_mask, (label_im == label,))
results = {label: result.get() for label, result in async_results.items()}
map
это петля