Mengapa pipa bernama selambat menulis ke file?

18

Saya mencoba memahami bagaimana pipa bernama bekerja sehingga saya dapat merampingkan komunikasi antar proses satu arah. Saya mengharapkan beberapa overhead karena menyalin data ke buffer melingkar, yang saya pikir disimpan dalam RAM, dan jadi saya berharap pipa menjadi jauh lebih cepat daripada menulis ke file (karena RAM adalah urutan besarnya lebih cepat daripada disk).

Sebaliknya, saya menemukan bahwa pipa bernama (atau pipa anonim) memiliki kecepatan yang sama dengan file. Ini pada desktop 3 GHz dengan disk drive biasa (bukan solid state), menjalankan Linux Ubuntu. Berikut adalah program pengujian yang disederhanakan dengan Python:

import sys
import time
import random

megabyte = "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for x in range(1024**2))

while True:
    before = time.time()
    sys.stdout.write(megabyte)
    after = time.time()
    sys.stderr.write("{} microseconds\n".format(1e6 * (after - before)))

Perpipaan langsung ke /dev/null:

python test.py > /dev/null

menghasilkan 2,1 mikrodetik (konstan) untuk setiap megabita.

Perpipaan ke file:

python test.py > /tmp/testout.txt

melompat antara 500 microseconds dan 930 microseconds (nilai yang lebih besar semakin umum karena file semakin besar --- mungkin, ini mencari ruang disk).

Kemudian pipa bernama:

mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe

menghasilkan 640 mikrodetik (konstan) dan pipa yang tidak disebutkan namanya:

python test.py | cat > /dev/null

juga menghasilkan 650 mikrodetik (konstan).

Adakah yang bisa menjelaskan mengapa kecepatan pipa lebih seperti kecepatan file daripada /dev/nullkecepatan? Mungkinkah saya memiliki saklar di suatu tempat yang mengatakan, "jalankan pipa melalui buffer berbasis file, daripada buffer berbasis RAM," dan dapatkah saya mengubah switch itu? Mungkinkah itu opsi kernel atau variabel shell?

Interpretasi lain: misalkan output disk melonjak antara 500 dan 930 mikrodetik karena 500 hanya pemipaan dan 930 sebenarnya menulis. Maka 500 ~ 640 untuk pemipaan dalam kedua kasus adalah setara. Namun, di bawah interpretasi itu, mengapa hanya ada dua faktor antara perpipaan dan benar-benar menulis ke disk? Situs web yang berbicara tentang disk RAM mengatakan bahwa disk RAM 50-200 kali lebih cepat daripada hard disk.

Jim Pivarski
sumber
1
Menulis ke /dev/nullsebenarnya cukup murah, sementara menulis di tempat lain - baik itu file, FIFO, pipa atau apa pun - jauh lebih mahal karena membutuhkan "banyak" upaya penanganan.
glglgl

Jawaban:

31

Anda tidak melihat manfaat kinerja karena Anda tidak benar-benar memukul disk saat menggunakan file - data sedang dalam perjalanan ke disk, tetapi utas eksekusi Anda tidak perlu menunggu sampai mendarat di sana, jadi Anda tidak benar - benar melihat penalti kecepatan memukul disk.

Jika Anda ingin menunggu operasi disk selesai untuk melihat berapa lambatnya, panggil a sync()(cara memvariasikan versi python Anda, lihat di sini ) - Anda akan melihat puluhan ribu mikrodetik hanya untuk disk mencari beberapa kali untuk mendapatkan file yang ditulis (dengan asumsi itu tidak memiliki semacam cache tulis cepat seperti pada pengontrol RAID).

Shane Madden
sumber
Kapan kita bisa berhenti mengkhawatirkan waktu mencari perangkat blok kita? :)
EEAA
5
@ EEAA Semua SSD, sepanjang waktu.
1
Anda benar: dengan sync()waktu penulisan disk menjadi rata-rata 74.000 mikrodetik. (Yang flush()saya lakukan dalam satu variasi pengujian saya tidak melakukannya.) Jadi interpretasi saya bahwa 500 ~ 640 mikrodetik per megabyte benar-benar merupakan overhead pipa masuk akal, terima kasih.
Jim Pivarski