В книге https://www.gnu.org/software/parallel/parallel_tutorial.html#number-of-simultainate-jobs
/usr/bin/time parallel -N0 sleep 1 :::: num128
(то же количество заданий, что и ядер)/usr/bin/time parallel -N0 --jobs 200% sleep 1 :::: num128
(2 задания на ядро)/usr/bin/time parallel -N0 --jobs 0 sleep 1 :::: num128
(как можно больше вакансий)Я предполагаю, что в книге речь идет о логических ядрах, а не о физических ядрах. Моя машина — Intel i7-13700HX 13-го поколения (16 ядер, 24 логических процессора).
num128
содержит разделенный новой строкой список чисел от 1 до 128. Фактическое значение не так важно, как количество занимаемых строк, что влияет на общее количество заданий.
Вопрос
Как вариант 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
.
Обнаружение ЦП — темная наука: мне действительно нужно больше пользователей, чтобы отправлять выходные данные из 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
таким же образом, вы обнаружите, что запускать более одного задания на каждый поток ЦП непрактично.
@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
Я не могу найти какой-либо инструмент под названием mmencode в Ubuntu, ближайшим был метамейл, в котором должна быть установлена зависимость от мменкода (ubuntuforums.org/showthread.php?t=1687668), но опубликованной версии метамэйла нет. Есть ли другой инструмент?
Попробуйте base64
вместо mmencode
. (И вы можете смело игнорировать жалобы tar
— результат в порядке).
@HanQi Спасибо за результат. Проблему можно объяснить запуском ядра, не поддерживающего ЦП. Я понятия не имею, как узнать, поддерживает ли ядро процессор, поэтому не могли бы вы попробовать использовать новейшее ядро, которое вы можете легко установить? Изменится ли выход?
@HanQi Можете ли вы также предоставить вывод lscpu --all --extended | pack
?
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