Логотип Zephyrnet

Чи ваша ментальна модель Bash Pipelines неправильна?

Дата:

[Майкл Лінч] зіткнувся з дивною ситуацією. Чому компіляція тоді запускала його програму майже в 10 разів швидше ніж просто запустити програму самостійно? [Майкл] зіткнувся з цією проблемою під час порівняльного аналізу проекту програмування, скоротив його до основних параметрів для повторюваності та аналізу та виявив, що він висвітлює неправильну розумову модель роботи конвеєрів bash.

Ось така ситуація. Перше, що робить скорочена програма [Майкла], це запускає таймер. Потім він просто читає та відраховує кілька байтів stdin, а потім друкує, скільки часу знадобилося для цього. При виконанні тестової програми таким чином це займає близько 13 мікросекунд.

$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast
bytes: 10
execution time: 13.549µs

При безпосередньому запуску (вже скомпільованої) програми час виконання збільшується до 162 мікросекунд.

$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes
bytes: 10
execution time: 162.195µs

Знову ж таки, єдина різниця між zig build run та ./zig-out/bin/count-bytes полягає в тому, що спочатку компілюється код, а потім негайно виконується. Другий просто запускає скомпільовану програму.

Як можна додати додатковий крок компіляції зменшити час виконання? Виявилося, що ментальна модель [Майкла] того, як працюють конвеєри bash, була неправильною, і він чудово справляється з пояснюючи, як вони насправді працюють і чому це спричинило дивну поведінку він бачив.

Коротше кажучи, команди в конвеєрі bash не запускаються послідовно. Усі вони запускаються одночасно й виконуються паралельно. Це означало, що при безпосередньому запуску програма лічильника байтів [Майкла] запускалася негайно. Потім він чекав, нічого не роблячи, близько 150 мікросекунд echo '00010203040506070809' | xxd -r -p частина конвеєра надала свої дані програмі для читання. Саме звідси виникає додатковий час виконання під час запуску вже скомпільованої версії.

То чому компіляція виконується швидше? Та сама основна причина: коли zig build run команда запускається, спочатку вона витрачає трохи часу на компіляцію програми. Потім, коли скомпільована програма фактично запускається (і починає свій таймер виконання), вхідні дані з конвеєра bash вже готові. Отже, щойно скомпільована програма виконується за менший час, оскільки вона не чекає, поки стануть доступними дані, отримані раніше в конвеєрі.

Це цікавий погляд на те, як насправді функціонують конвеєри bash під капотом, і ми в захваті від деталей, які [Майкл] вкладає у всю подорож і пояснення. Рано чи пізно такі деталі спливають і викликають підняття брів, як у користувача, який відкрив проблемні крайні випадки щодо пробілів у командах ssh.

spot_img

Остання розвідка

spot_img