У меня есть несколько блоков данных, каждый из которых состоит из либо 6 пунктов, либо 24 пункта, и каждый пункт анализируется отдельно. Код анализа
не мой. По независящим от меня причинам каждый элемент должен обрабатываться
однопоточно.
Но я создал скрипт/функцию, которая обрабатывает один такой
блок данных в раз, создавая 6 или 24 процесса по мере необходимости, по одному
процессу на элемент, используя python.joblib.Parallel(). Это прекрасно работает.
Я могу заранее знать, содержит ли блок 6 или 24 элемента.
Вычисление одного элемента длится примерно 4 часа. Блок элементов, работающих параллельно, длится примерно одинаково. Так что это идеальный случай для распараллеливания.
У меня есть одна рабочая станция с 40 потоками, доступными для
использования. Таким образом, я не могу запустить более одного блока из 24 элементов, но остается достаточно места для запуска двух блоков из 6 элементов. А если большие блоки завершатся раньше, останется место для одновременной работы 6 маленьких блоков.
Количество блоков данных по 24 и 6 элементов в пуле равно не
обязательно равны или фиксированы.
Вот что я хотел бы сделать:
Мне хотелось бы обработать целый пул данных разного размера. блоков из сценария-оболочки, при этом сводя к минимуму общее время, затрачиваемое на это, за счет отсутствия слишком большого количества простаивающих ядер.
Моя первоначальная идея заключалась в следующем: иметь блоки данных в двух пулах по размеру и иметь два вызова Parallel для запуска моей функции обработки блоков: один отправляет отдельные задания из пула больших блоков, а другой отправляет два задания из пула небольшие блоки. Но потом я понял, что Parallel будет ждать завершения задач, поэтому второй пул запустится только после завершения работы первого.
Я знаю, что планировщики кластерных вычислений справляются с такими задачами, но я работаю на одной рабочей станции и у меня нет планировщика. Файлы данных слишком велики для пропускной способности нашей сети, поэтому покупать облачные вычисления и планировать там задания вообще непрактично.
Растворение блоков данных и создать один огромный пул отдельных элементов из всех блоков данных, вероятно, было бы возможно, и было бы проще и эффективнее всего затем распараллелить, но с моей стороны потребовалось бы немалое количество усилий по переосмыслению и рефакторинг моего кода обработки, чтобы приспособить это. Я могу сделать это в долгосрочной перспективе, но в краткосрочной перспективе я хотел бы другой путь.
Последний вариант, который я могу придумать. , это... иметь два экземпляра сценария-оболочки, один экземпляр для больших блоков, отправляющих отдельные задачи, и один экземпляр для маленьких блоков, отправляющих пары задач, и полагаться на синтаксис bash для их одновременного запуска. Но это кажется... неудовлетворительным.
Есть ли аккуратный способ сделать это, не усложняя мою настройку? ?
PS.: На самом деле я даже не знаю, смогу ли я вложить вызовы Parallel, причем самый внутренний вызов порождает больше процессов, чем самые внешние n_jobs, Я еще не пробовал, так как понял свой первоначальный план не сработал, и я еще не придумал лучшего. (И я понимаю, что это, вероятно, плохой дизайн программирования.) Система
python 3.12.8, на старая рабочая станция HP с Ubuntu 22.04 LTS. Я использую серверную часть Parallel по умолчанию, но я недостаточно разбираюсь в ИТ, чтобы сделать осознанный выбор.
[b]Вот контекст того, что я пытаюсь сделать:[/b] [list] [*]У меня есть несколько блоков данных, каждый из которых состоит из либо 6 пунктов, либо 24 пункта, и каждый пункт анализируется отдельно. Код анализа не мой. По независящим от меня причинам каждый элемент должен обрабатываться однопоточно. [*]Но я создал скрипт/функцию, которая обрабатывает один такой блок данных в раз, создавая 6 или 24 процесса по мере необходимости, по одному процессу на элемент, используя python.joblib.Parallel(). Это прекрасно работает. [*]Я могу заранее знать, содержит ли блок 6 или 24 элемента. [*]Вычисление одного элемента длится примерно 4 часа. Блок элементов, работающих параллельно, длится примерно одинаково. Так что это идеальный случай для распараллеливания. [*]У меня есть одна рабочая станция с 40 потоками, доступными для использования. Таким образом, я не могу запустить более одного блока из 24 элементов, но остается достаточно места для запуска двух блоков из 6 элементов. А если большие блоки завершатся раньше, останется место для одновременной работы 6 маленьких блоков. [*]Количество блоков данных по 24 и 6 элементов в пуле равно не обязательно равны или фиксированы. [/list] [b]Вот что я хотел бы сделать:[/b] Мне хотелось бы обработать целый пул данных разного размера. блоков из сценария-оболочки, при этом сводя к минимуму общее время, затрачиваемое на это, за счет отсутствия слишком большого количества простаивающих ядер. [list] [*]Моя первоначальная идея заключалась в следующем: иметь блоки данных в двух пулах по размеру и иметь два вызова Parallel для запуска моей функции обработки блоков: один отправляет отдельные задания из пула больших блоков, а другой отправляет два задания из пула небольшие блоки. Но потом я понял, что Parallel будет ждать завершения задач, поэтому второй пул запустится только после завершения работы первого.
[*] Я знаю, что планировщики кластерных вычислений справляются с такими задачами, но я работаю на одной рабочей станции и у меня нет планировщика. Файлы данных слишком велики для пропускной способности нашей сети, поэтому покупать облачные вычисления и планировать там задания вообще непрактично.
[*]Растворение блоков данных и создать один огромный пул отдельных элементов из всех блоков данных, вероятно, было бы возможно, и было бы проще и эффективнее всего затем распараллелить, но с моей стороны потребовалось бы немалое количество усилий по переосмыслению и рефакторинг моего кода обработки, чтобы приспособить это. Я могу сделать это в долгосрочной перспективе, но в краткосрочной перспективе я хотел бы другой путь.
[*]Последний вариант, который я могу придумать. , это... иметь два экземпляра сценария-оболочки, один экземпляр для больших блоков, отправляющих отдельные задачи, и один экземпляр для маленьких блоков, отправляющих пары задач, и полагаться на синтаксис bash для их одновременного запуска. Но это кажется... неудовлетворительным.
[/list] Есть ли аккуратный способ сделать это, не усложняя мою настройку? ? PS.: На самом деле я даже не знаю, смогу ли я вложить вызовы Parallel, причем самый внутренний вызов порождает больше процессов, чем самые внешние n_jobs, Я еще не пробовал, так как понял свой первоначальный план не сработал, и я еще не придумал лучшего. (И я понимаю, что это, вероятно, плохой дизайн программирования.) [b]Система[/b] python 3.12.8, на старая рабочая станция HP с Ubuntu 22.04 LTS. Я использую серверную часть Parallel по умолчанию, но я недостаточно разбираюсь в ИТ, чтобы сделать осознанный выбор.