Многопроцессорный пул — большинство воркеров загружены, но все еще простаивают

В скрипте Python 2.7 первый многопроцессорный код для обработки большого куска массива numpy. Это в основном блок кадра проекционного луча между планом изображения и декартовой (мировой) плоскостью. Эта часть, называемая poo1, работает нормально.

Далее в сценарии я пытаюсь воспроизвести многопроцессорный код для проецирования большого количества изображений с помощью этого кадра проекционного луча.

Кажется, что работает всего 4-6 воркеров, но все они готовы к работе по наполнению данными. pool2 создает рабочих, они медленно растут в использовании памяти, только до 6 из них используют мощность процессора.

Снимок экрана: Воркеры, которые не работают при многопроцессорности

Примечания:

  • Нет возврата вывода для получения из многопроцессорной функции, вывода, если файл пишется в папку;
  • Не беспокойтесь о проблемах с объемом памяти, доступно полТБ;
  • Не беспокойтесь о порядке процесса;
  • Количество воркеров - это физическое ядро ​​ЦП - 1 = 27;
  • Длина списка заданий для распределения (paramsGeoRef) может быть от 1 до 250 строк.

Информация об аргументах:

  • Frameclock, массивный ndarray, может быть ГБ
  • A1 : ndarray, может быть сотни МБ
  • A2 : ndarray, может быть сотни МБ
  • B1 : целочисленное значение
  • B2 : целочисленное значение
  • имя_файла: строка, имя
  • D1: строка, путь
  • D2: строка, путь
  • D3: строка, путь
  • P1: небольшой массив
  • P2: небольшой массив

Упрощенный код выглядит следующим образом:

    def georef(paramsGeoRef):

        #Pseudo workflow
        """
        - unpack arguments, Frameclock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2 <== paramsGeoRef
        - Loading tif image
        - Evergy convertion
            with function and P1, P2
        - Proportional projection of the image
            - Frameclock, A1, A2
        - Evergy convertion
            with function and P1, P2
        - Figure creation
        - Geotiff creation
        - export into file figure, geotiff and numpy file
        """
        return None

if __name__ == '__main__':

    paramsGeoRef = []
    for im in imgfiles:
        paramsGeoRef.append([Frameclock, A1, A2, B1, B2, fileName, D1 , D2 , D3 , P1 , P2])
    if flag_parallel:
        cpus = multiprocessing.cpu_count()
        cpus = cpus - 1
        pool2 = multiprocessing.Pool(processes=cpus)
        pool2.map(georef, paramsGeoRef)
        pool2.close()
        pool2.join()

Я пробовал разные подходы, например:

Распаковать аргументы перед:

def star_georef(Frameclock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2):
    return georef(*paramsGeoRef)

def georef(paramsGeoRef):
    #Pseudo workflow...
    return None

Использован другой тип карты:

pool2.imap_unordered()

Что не так? Почему этот метод работает для перемалывания массива numpy, а не для этой цели? Нужно обрабатывать размер фрагмента?

Может быть, мне нужно будет кормить рабочих, как только они появятся в генераторе заданий?


person Alex C.    schedule 04.10.2019    source источник
comment
Я подозреваю, что узкое место связано с передачей аргумента Frameclock ГБ каждому из процессов. Возможно, было бы лучше сделать это mmap и передать его, чтобы избежать связанных с этим накладных расходов (независимо от того, сколько оборудования вы используете для этого).   -  person martineau    schedule 04.10.2019
comment
Я сохраняю Frameclock, A1 и A2 в .npy с помощью numpy. Вместо этого я загрузил его в georef. Резкий прирост эффективности!!! Спасибо   -  person Alex C.    schedule 09.10.2019
comment
Рад слышать — добро пожаловать.   -  person martineau    schedule 09.10.2019
comment
Вопрос: использование memmap (np.memmap) может быть даже более эффективным, чем рассол, такой как .npy? Особенно, когда вы использовали сотни МБ ndarray.   -  person Alex C.    schedule 10.10.2019
comment
Да, использование карты памяти позволит эффективно обмениваться данными между процессами — причина, по которой я первоначально предложил ее использовать.   -  person martineau    schedule 10.10.2019


Ответы (1)


Следуя совету Мартино,

Я сохраняю аргументы Frameclock, A1 и A2 с помощью numpy в формате .npy. Затем я загружаю .npy внутрь распараллеленного .

такие как :

def georef(paramsGeoRef):

    #Pseudo workflow
    """
    - unpack arguments, Frameblock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2 <== paramsGeoRef
    - load Frameblock from his .npy
    - load A1 from his .npy
    - load A2 from his .npy
    - Loading tif image
    - Evergy convertion
        with function and P1, P2
    - Proportional projection of the image
        - Frameclock, A1, A2
    - Evergy convertion
        with function and P1, P2
    - Figure creation
    - Geotiff creation
    - export into file figure, geotiff and numpy file
    """
    return None

Даже с сохранением и загрузкой это резкое повышение эффективности! Все рабочие работы.

person Alex C.    schedule 09.10.2019