Як перезавантажити ваші робочі процеси bash паралельно GNU

GNU parallel- це інструмент командного рядка для паралельного запуску завдань.

parallelє чудовим і належить до набору інструментів кожного програміста. Але спочатку я знайшов документи трохи приголомшливими. На щастя, ви можете почати бути корисним, parallelвикористовуючи лише кілька основних команд.

Чому parallelтак корисно?

Давайте порівняємо послідовне та паралельне виконання одного і того ж обчислювального завдання.

Уявіть, у вас є папка із аудіофайлами .wav для конвертації у .flac:

Це досить великі файли, кожен із них - принаймні гігабайт.

Для перетворення файлів ми використаємо ще один чудовий інструмент командного рядка, ffmpeg. Ось те, що нам потрібно запустити для кожного файлу.

ffmpeg -i audio1.wav audio1.flac

Давайте напишемо сценарій для послідовного перетворення кожного:

# convert.sh ffmpeg -i audio1.wav audio1.flac ffmpeg -i audio2.wav audio2.flac ffmpeg -i audio3.wav audio3.flac ffmpeg -i audio4.wav audio4.flac ffmpeg -i audio5.wav audio5.flac

Ми можемо визначити час виконання завдання шляхом попереднього timeвиклику при виклику сценарію з терміналу. timeнадрукує реальний час, що минув під час виконання.

time ./convert.sh

Наш сценарій закінчується трохи більше хвилини.

Непогано. Але тепер давайте запускати це паралельно!

Ми не повинні нічого змінювати у своєму сценарії. За допомогою -aпрапора ми можемо направити наш сценарій безпосередньо в parallel. parallelбуде запускати кожен рядок як окрему команду.

parallel -a ./convert.sh

За допомогою parallelнашого перетворення відбулося трохи більше половини часу. Приємно!

Маючи лише п’ять файлів, ця різниця не є такою великою проблемою. Але завдяки більшим спискам і довшим завданням ми можемо заощадити багато часу parallel.

Я зіткнувся parallelпід час роботи із завданням обробки даних, яке, швидше за все, могло б тривати годину або більше, якщо робити це послідовно. З цим parallel, це зайняло лише кілька хвилин.

parallelпотужність також залежить від вашого комп'ютера. Intel i7 мого MacBook Pro має лише 4 ядра. Навіть це невелике завдання підштовхнуло їх усіх до межі:

Більш потужні комп’ютери можуть мати процесори з 8, 16 або навіть 32 ядрами, що забезпечує значну економію часу за допомогою паралелізації ваших завдань.

Бути корисним з parallel

Інша велика перевага - parallelце стислість і простота. Почнемо з неприємного сценарію Python і перетворимо його на чистий виклик parallel.

Ось сценарій Python для перетворення нашого аудіофайлу:

import subprocess path = Path.home()/'my-data-here' for audio_file in list(path.glob('*.wav')): cmd = ['ffmpeg', '-i', str(audio_file), f'{audio_file.name.split(".")[0]}.flac'] subprocess.run(cmd, stdout=subprocess.PIPE)

Так! Це насправді багато коду, про який слід подумати, щоб просто перетворити деякі файли. (Для запуску потрібно приблизно 1,2 хвилини).

Давайте перетворимо наш Python на parallel.

Виклик сценарію за допомогою parallel -a

parallel -a your-script-here.sh - це приємний одношаровий вкладиш, який ми використовували вище для конвеєрування в нашому скрипті bash.

Це чудово, але вимагає від вас виписати скрипт bash, який ви хочете виконати. У нашому прикладі, ми все ще виписували кожен індивідуальний виклик ffmpegв системі convert.sh.

Труби та рядкова інтерполяція з parallel

На щастя, це parallelдає нам можливість convert.shповністю видалити .

Ось усе, що нам потрібно запустити, щоб здійснити наше перетворення:

ls *.wav | parallel ffmpeg -i {} {.}.flac

Давайте розберемо це.

Ми отримуємо список усіх файлів .wav у нашому каталозі за допомогою ls *.wav. Тоді ми перекладаємо ( |) цей список parallel.

Parallel надає кілька корисних способів інтерполяції рядків, тому наші файлові шляхи вводяться правильно.

Перший {}, який parallelавтоматично замінює один рядок з нашого вводу.

Другим оператором є {.}, який введе один рядок, але з видаленими розширеннями файлів.

Якби ми розширили команду, запущену parallelдля нашого першого рядка введення, ми побачили б ...

ffmpeg -i audio1.wav audio1.flac

Сварки з Parallel

Як виявляється, нам навіть не потрібно lsвиконувати завдання, щоб виконати своє завдання. Ми можемо зробити ще простішими:

parallel ffmpeg -i {} {.}.flac ::: *.wav

Аргументи, передані parallelпісля команди, розділяються символом :::. У цьому випадку ми аргументуємо *.wav, що надасть список усіх файлів .wav у нашому каталозі. Ці файли стають вхідними даними для нашої надзвичайно швидкої parallelроботи.

Fun fact: parallel was built by Ole Tange and published in 2011. According to him, you can use the tool for research without citing the source paper for the modest fee of 10,000 euros!

Thanks for reading!