Как да презаредите вашите 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!