Как GNU параллельно выполняет несколько заданий на ядро?

В книге https://www.gnu.org/software/parallel/parallel_tutorial.html#number-of-simultainate-jobs

  1. /usr/bin/time parallel -N0 sleep 1 :::: num128 (то же количество заданий, что и ядер)
  2. /usr/bin/time parallel -N0 --jobs 200% sleep 1 :::: num128 (2 задания на ядро)
  3. /usr/bin/time parallel -N0 --jobs 0 sleep 1 :::: num128 (как можно больше вакансий)

Я предполагаю, что в книге речь идет о логических ядрах, а не о физических ядрах. Моя машина — Intel i7-13700HX 13-го поколения (16 ядер, 24 логических процессора).

num128 содержит разделенный новой строкой список чисел от 1 до 128. Фактическое значение не так важно, как количество занимаемых строк, что влияет на общее количество заданий.

  1. Вариант 1 использовал 24 задания и занял 6,333 секунды.
  2. Вариант 2 использовал 48 заданий и занял 3,249 секунды.
  3. Вариант 3 использовал 128 заданий и занял 1,421 секунды.

Вопрос

Как вариант 2 помещает 2 задания на одно ядро ​​и выполняет оба за 1 секунду? (общий ввод требует 3 итераций распределения заданий и сна)?

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

Параллельно ли выполняются оба режима сна в фоновом режиме на одном ядре, поэтому их время перекрывается?

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

Интересно, работает ли этот пример с несколькими заданиями на ядро ​​только потому, что несколько таймингов сна могут перекрываться, когда они запускаются в фоновом режиме, и если бы я перешел на другую команду, которая не может выполняться одновременно, было бы бессмысленно запускать несколько заданий на ядро, как вариант 2 и 3.

В варианте 3 что ограничивает верхний предел «максимально возможным количеством параллельных работ»?

Основываясь на этих трех примерах, я думаю, что мне всегда следует выбирать вариант 3 как самый быстрый. Когда это уже не так?

Я попытался расширить границы, увеличив размер входных данных в 2 раза с помощью /usr/bin/time parallel -N0 --jobs 0 sleep 1 :::: <(cat num128 num128), и все же все было сделано за 1 итерацию за 1,83 секунды.

Краткое содержание

Я не понимаю модели распределения работы для вариантов 2 и 3, почему вариант 2 работает быстрее, чем я ожидал, почему на время варианта 3 не влияет количество заданий по логическим ядрам, и на него не влияет увеличение размера входных данных, и демонстрации книги относятся только к команде sleep и поэтому не могут быть обобщены.

Если вы хотите посчитать итерации

Измените приведенные выше примеры команд, обернув сон с помощью echo и наблюдая за циклами печати.

'echo start job number {#} job slot {%};sleep 1;echo finish job number {#} job slot {%}'

Возможно, важные причуды

parallel --number-of-cores --> 12 (не соответствует 16 из системной информации?)

parallel --number-of-sockets --> 1

parallel --number-of-threads --> 24

Также есть варианты --use-cores-instead-of-threads и --use-sockets-instead-of-threads.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обнаружение ЦП — темная наука: мне действительно нужно больше пользователей, чтобы отправлять выходные данные из lscpu, /sys/devices/system/cpu* и /proc/cpuinfo и каковы ожидаемые интерпретируемые значения.

Это объясняет, почему parallel --number-of-cores дает 12 вместо правильных 16.

Причина, по которой может иметь смысл запускать -j200%, заключается в том, что некоторые вычисления требуют длительного ожидания — sleep 1 является крайним примером этого: нет проблем в параллельном запуске двух sleep 1 в одном и том же потоке ЦП. То же самое касается таких задач, как wget, где вы зависите от сетевого ввода-вывода.

Если вы задали задания, требующие больших вычислительных ресурсов (например, bzip2 -9), то, как правило, не имеет смысла запускать параллельно больше заданий, чем имеется потоков ЦП.

Технически GNU Parallel не запускает работу «на ядре». Это просто начало работы. ОС определяет, для какого потока ЦП запланировать задание.

Вы можете запустить множество sleep 1 в одном потоке ЦП, поскольку они занимают очень мало процессорного времени. Таким образом, предел, который вы собираетесь достичь, - это не вычислительная мощность ЦП, а другие ограничения (например, дескрипторы файлов - GNU Parallel использует 4 на одно одновременное задание).

Я считаю, что основная путаница может заключаться в том, что запуск нескольких экземпляров sleep 1 в одном потоке ЦП возможен, поскольку эти команды не требуют большой мощности ЦП. Однако если вы попытаетесь запустить bzip2 -9 таким же образом, вы обнаружите, что запускать более одного задания на каждый поток ЦП непрактично.

I really need more users to send output from lscpu, /sys/devices/system/cpu* and /proc/cpuinfo and what the expected interpreted values are Собираются ли они в какой-либо форме в настоящее время? Комментарии здесь имеют ограничение на количество символов. Для моего lscpu выдает количество потоков на ядро: 2, количество ядер на сокет: 12, сокет(а): 1. /sys/devices/system/cpu* | sort -V содержит папки от cpu0 до cpu23. cat /proc/cpuinfo показывает информацию о процессоре от 0 до 23
Han Qi 07.05.2024 07:07

@HanQi pack() { bzip2 -9 | mmencode; }; lscpu | pack; cat /proc/cpuinfo | pack; tar c /sys/devices/system/cpu* | pack Опубликовать вывод как ошибку на savannah.gnu.org/bugs/?group=parallel&func=additem

Ole Tange 07.05.2024 09:24

Я не могу найти какой-либо инструмент под названием mmencode в Ubuntu, ближайшим был метамейл, в котором должна быть установлена ​​зависимость от мменкода (ubuntuforums.org/showthread.php?t=1687668), но опубликованной версии метамэйла нет. Есть ли другой инструмент?

Han Qi 08.05.2024 09:55

Попробуйте base64 вместо mmencode. (И вы можете смело игнорировать жалобы tar — результат в порядке).

Ole Tange 08.05.2024 14:53

@HanQi Спасибо за результат. Проблему можно объяснить запуском ядра, не поддерживающего ЦП. Я понятия не имею, как узнать, поддерживает ли ядро ​​процессор, поэтому не могли бы вы попробовать использовать новейшее ядро, которое вы можете легко установить? Изменится ли выход?

Ole Tange 14.05.2024 13:47

@HanQi Можете ли вы также предоставить вывод lscpu --all --extended | pack?

Ole Tange 14.05.2024 16:25

Другие вопросы по теме