Adlandırılmış bir kanal neden bir dosyaya yazmak kadar yavaş?


18

Tek yönlü süreçler arası iletişimi kolaylaştırmak için adlandırılmış yöneltmelerin nasıl çalıştığını anlamaya çalışıyorum. RAM'de depolandığını düşündüğüm dairesel bir araca veri kopyalaması nedeniyle biraz ek yük bekliyorum ve bu yüzden borunun bir dosyaya yazmaktan çok daha hızlı olmasını bekledim (çünkü RAM diskten daha büyük boyutlu siparişler).

Bunun yerine, adlandırılmış borunun (veya anonim borunun) bir dosya ile aynı hızda olduğunu buldum. Bu, Ubuntu Linux çalıştıran sıradan bir disk sürücüsüne (katı hal değil) sahip 3 GHz'lik bir masaüstündedir. İşte Python'da basitleştirilmiş bir test programı:

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)))

Doğrudan boru tesisatı /dev/null:

python test.py > /dev/null

her megabayt için 2.1 mikrosaniye (sabit) verir.

Dosyaya aktarma:

python test.py > /tmp/testout.txt

500 mikrosaniye ve 930 mikrosaniye arasında atlar (dosya büyüdükçe büyük değer daha yaygın hale gelir --- muhtemelen disk alanı arıyor).

Sonra adlandırılmış boru:

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

640 mikrosaniye (sabit) ve isimsiz bir boru verir:

python test.py | cat > /dev/null

ayrıca 650 mikrosaniye (sabit) verir.

Herkes borunun hızının neden dosyanın hızından daha yüksek olduğunu açıklayabilir /dev/nullmi? "Boruları RAM tabanlı bir tampondan ziyade dosya tabanlı bir tampondan çalıştır" diyen bir yerde bir anahtar alabilir miyim ve bu anahtarı değiştirebilir miyim? Bir çekirdek seçeneği veya bir kabuk değişkeni olabilir mi?

Başka bir yorum: varsayalım ki disk çıktısı 500 ve 930 mikrosaniye arasında atlıyor, çünkü 500 sadece piping yapıyor ve 930 aslında yazıyor. Daha sonra her iki durumda da boru tesisatı için 500 ~ 640 eşdeğerdir. Ancak, bu yorum altında, neden borularla gerçekte diske yazmak arasında sadece iki faktör vardır? RAM disklerden bahseden web siteleri, RAM disklerin sabit disklerden 50-200 kat daha hızlı olduğunu söylüyor.


1
Yazma /dev/nullçok daha bunun çaba işleme "çok şey" ihtiyacı olarak pahalı - it a dosya, bir FIFO, bir boru ya da her neyse olun - başka bir yerde yazarken, oldukça ucuz aslında.
glglgl

Yanıtlar:


31

Herhangi bir performans avantajı görmüyorsunuz çünkü bir dosyayı kullanırken diske gerçekten vurmuyorsunuz - veriler diske doğru gidiyor, ancak yürütme dizinizin buraya gelmesini beklemesi gerekmiyor, bu nedenle aslında görme diski vurma hızı cezası.

Disk işleminin ne kadar yavaşladığını görmek için tamamlanmasını beklemek istiyorsanız, a sync()(python sürümünüzde nasıl değişiklik gösterir, buraya bakın ) - sadece diskiniz için on binlerce mikrosaniye bakacaksınız. dosyayı yazmak için birkaç kez arayın (bir RAID denetleyicisinde olduğu gibi bir tür hızlı yazma önbelleğine sahip olmadığını varsayarak).


Blok cihazlarımızın arama süresi hakkında endişelenmeyi ne zaman bırakacağız? :)
EEAA

5
@EEAA Her zaman tüm SSD'ler.

1
Haklısın: bir sync()disk yazma süresi ile ortalama 74.000 mikrosaniye olur. ( flush()Testimin bir varyasyonunda yapıyordum bunu yapmadım.) O zaman benim yorumum megabayt başına 500 ~ 640 mikrosaniyenin gerçekten borunun tepesi olduğu mantıklı, teşekkürler.
Jim Pivarski
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.