Zephyrnet logó

Rossz a Bash Pipelines mentális modellje?

Találka:

[Michael Lynch] furcsa helyzetbe került. Miért volt a fordítás akkoriban közel 10-szer futtatva a programját gyorsabb mint a program futtatása önmagában? [Michael] belefutott ebbe a problémába egy programozási projekt benchmarkolása során, lefuttatta azt a megismételhetőség és az elemzés alapvető elemeihez, és felfedezte, hogy a bash-csővezetékek működésének helytelen mentális modelljét emelte ki.

Íme a helyzet. Az első dolog [Michael] lecsökkentő programja elindít egy időzítőt. Ezután egyszerűen beolvas és megszámol néhány bájtot stdin, majd kinyomtatja, hogy mennyi időbe telt, mire ez megtörtént. Ha a tesztprogramot a következő módon futtatja, az körülbelül 13 mikroszekundumot vesz igénybe.

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

A (már lefordított) program közvetlen futtatásakor a végrehajtási idő 162 mikroszekundumra duzzad.

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

Ismét csak az egyetlen különbség zig build run és a ./zig-out/bin/count-bytes az, hogy először lefordítja a kódot, majd azonnal lefuttatja. A második egyszerűen lefuttatja a lefordított programot.

Hogyan lehet hozzáadni egy további fordítási lépést csökkenés a végrehajtási idő? Kiderült, hogy [Michael] mentális modellje a bash csővezetékek működéséről helytelen volt, és nagyszerű munkát végez elmagyarázza, hogyan működnek valójában, és miért okozta ez a furcsa viselkedést ő látott.

Röviden, a bash folyamatban lévő parancsok nem egymás után indulnak el. Mindegyik egyszerre indul el és párhuzamosan fut. Ez azt jelentette, hogy közvetlen futtatáskor [Michael] bájtszámláló programja azonnal elindult. Aztán körülbelül 150 mikromásodpercig várt, és nem csinált semmit, míg a echo '00010203040506070809' | xxd -r -p a folyamat egy része eljutott ahhoz, hogy a program beolvassa adatait. Innen származik az extra végrehajtási idő a már lefordított verzió futtatásakor.

Akkor miért fut először gyorsabban a fordítás? Ugyanaz az alapvető ok: amikor a zig build run parancs elindul, először a program fordításával tölt egy kis időt. Aztán amikor a lefordított program ténylegesen elindul (és elindítja a végrehajtási időzítőjét), a bash folyamat bemeneti adatai már készen állnak. Így a frissen lefordított program rövidebb idő alatt fut le, mert nem ül és várja, hogy a folyamatban lévő korábbi adatok elérhetővé váljanak.

Érdekes pillantást vetni arra, hogyan is működnek a csővezetékek a motorháztető alatt, és nagyon örülünk annak, hogy [Micheal] az egész utazásba és magyarázatba fekteti a részleteket. Előbb vagy utóbb az ehhez hasonló részletek felbukkannak, és felvonják a szemöldökét, például annak a felhasználónak, aki felfedezte problémás szélsőséges esetek az ssh parancsok szóközeivel kapcsolatban.

spot_img

Legújabb intelligencia

spot_img