Logo Zephyrnet

Mô hình tinh thần của bạn về đường ống Bash có sai không?

Ngày:

[Michael Lynch] gặp phải một tình huống kỳ lạ. Tại sao biên dịch rồi chạy chương trình của anh ấy gần gấp 10 lần nhanh hơn hơn là chỉ chạy chương trình một mình? [Michael] gặp phải vấn đề này khi đang đánh giá một dự án lập trình, giảm bớt các yếu tố cần thiết để có thể lặp lại và phân tích, đồng thời phát hiện ra rằng nó nêu bật một mô hình tinh thần không chính xác về cách hoạt động của các đường dẫn bash.

Đây là tình huống. Điều đầu tiên mà chương trình rút gọn của [Michael] thực hiện là bắt đầu tính giờ. Sau đó, nó chỉ cần đọc và đếm một số byte từ stdin, sau đó in ra mất bao lâu để điều đó xảy ra. Khi chạy chương trình thử nghiệm theo cách sau, sẽ mất khoảng 13 micro giây.

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

Khi chạy trực tiếp chương trình (đã được biên dịch), thời gian thực hiện sẽ tăng lên 162 micro giây.

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

Một lần nữa, sự khác biệt duy nhất giữa zig build run./zig-out/bin/count-bytes là việc đầu tiên biên dịch mã, sau đó chạy nó ngay lập tức. Thứ hai chỉ đơn giản là chạy chương trình đã biên dịch.

Làm thế nào có thể thêm một bước biên dịch bổ sung giảm thời gian thực hiện? Hóa ra mô hình tinh thần của [Michael] về cách hoạt động của đường ống bash là không chính xác và anh ấy đã làm rất tốt việc giải thích cách chúng thực sự hoạt động và tại sao điều đó gây ra hành vi kỳ lạ anh ấy đang nhìn thấy.

Nói tóm lại, các lệnh trong đường dẫn bash không được khởi chạy tuần tự. Tất cả chúng đều được khởi chạy cùng lúc và thực hiện song song. Điều đó có nghĩa là khi chạy trực tiếp, chương trình đếm byte của [Michael] sẽ khởi chạy ngay lập tức. Sau đó, nó chờ đợi không làm gì nhiều trong khoảng 150 micro giây trong khi echo '00010203040506070809' | xxd -r -p một phần của quy trình đã xoay quanh việc cung cấp dữ liệu của nó cho chương trình đọc. Đây là nơi có thêm thời gian thực hiện khi chạy phiên bản đã được biên dịch.

Vậy tại sao việc biên dịch lần đầu tiên lại chạy nhanh hơn? Lý do cơ bản giống nhau: khi zig build run lệnh bắt đầu, trước tiên nó sẽ dành một ít thời gian để biên dịch chương trình. Sau đó, khi chương trình đã biên dịch thực sự được khởi chạy (và bắt đầu bộ đếm thời gian thực thi của nó), dữ liệu đầu vào từ đường dẫn bash đã sẵn sàng. Vì vậy, chương trình mới được biên dịch sẽ thực thi trong thời gian ngắn hơn vì nó không phải chờ đợi dữ liệu từ trước đó trong quy trình có sẵn.

Đó là một cái nhìn thú vị về cách các đường ống bash thực sự hoạt động dưới mui xe và chúng tôi rất vui với chi tiết [Micheal] đưa vào toàn bộ hành trình và lời giải thích. Sớm hay muộn, những chi tiết như thế này sẽ xuất hiện và khiến một số người phải nhướng mày, giống như người dùng đã phát hiện ra các trường hợp rắc rối liên quan đến khoảng trắng trong lệnh ssh.

tại chỗ_img

Tin tức mới nhất

tại chỗ_img