किसी फ़ाइल में लिखने के लिए एक नामित पाइप उतना धीमा क्यों है?


18

मैं यह समझने की कोशिश कर रहा हूं कि नामित पाइप कैसे काम करते हैं ताकि मैं अपने एक-तरफा इंटरप्रोसेस संचार को सुव्यवस्थित कर सकूं। मैं एक परिपत्र बफ़र में डेटा की नकल करने के कारण कुछ ओवरहेड की उम्मीद करता हूं, जो मुझे लगता था कि रैम में संग्रहीत है, और इसलिए मुझे उम्मीद थी कि पाइप एक फ़ाइल से लिखने की तुलना में बहुत तेज़ होगा (क्योंकि रैम डिस्क से अधिक परिमाण का आदेश है)।

इसके बजाय, मैंने पाया कि नामित पाइप (या अनाम पाइप) फ़ाइल के समान गति के बारे में है। यह उबंटू लिनक्स को चलाने वाले एक साधारण डिस्क ड्राइव (ठोस स्थिति नहीं) के साथ 3 गीगाहर्ट्ज़ डेस्कटॉप पर है। यहाँ पायथन में एक सरलीकृत परीक्षण कार्यक्रम है:

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

सीधे पाइपिंग /dev/null:

python test.py > /dev/null

प्रत्येक मेगाबाइट के लिए 2.1 माइक्रोसेकंड (स्थिर) उपज देता है।

फ़ाइल में पाइप करना:

python test.py > /tmp/testout.txt

500 माइक्रोसेकंड और 930 माइक्रोसेकंड के बीच कूदता है (बड़ा मूल्य अधिक सामान्य हो जाता है क्योंकि फ़ाइल बड़ी हो जाती है --- संभवतः, यह डिस्क स्थान की तलाश में है)।

फिर नामित पाइप:

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

640 माइक्रोसेकंड (निरंतर) और एक अनाम पाइप पैदावार:

python test.py | cat > /dev/null

650 माइक्रोसेकंड (स्थिर) पैदावार भी देता है।

क्या कोई समझा सकता है कि पाइप की गति फ़ाइल की गति से अधिक /dev/nullक्यों है? क्या मेरे पास एक स्विच हो सकता है जो कहता है, "रैम-आधारित बफर के बजाय, फ़ाइल-आधारित बफर के माध्यम से पाइप चलाएं," और क्या मैं उस स्विच को बदल सकता हूं? यह एक कर्नेल विकल्प या शेल चर हो सकता है?

एक और व्याख्या: मान लीजिए कि डिस्क आउटपुट 500 और 930 माइक्रोसेकंड के बीच कूदता है क्योंकि 500 ​​बस पाइपिंग है और 930 वास्तव में लिख रहा है। फिर दोनों मामलों में पाइपिंग के लिए 500 ~ 640 बराबर है। हालांकि, उस व्याख्या के तहत, पाइपिंग और वास्तव में डिस्क पर लिखने के बीच दो का एक कारक क्यों है? रैम डिस्क के बारे में बात करने वाली वेबसाइटें कहती हैं कि रैम डिस्क हार्ड डिस्क की तुलना में 50-200 गुना तेज हैं।


1
लेखन /dev/nullवास्तव में काफी सस्ता है, कहीं और लिखते हुए - यह एक फ़ाइल, एक फीफो, एक पाइप या जो कुछ भी है - बहुत अधिक महंगा है क्योंकि इसे संभालने के प्रयास की "बहुत" जरूरत है।
ग्लोगल

जवाबों:


31

आपको कोई प्रदर्शन लाभ दिखाई नहीं दे रहा है क्योंकि आप वास्तव में डिस्क का उपयोग नहीं कर रहे हैं जब एक फ़ाइल का उपयोग कर रहे हैं - डिस्क पर डेटा के रास्ते पर, लेकिन आपके निष्पादन थ्रेड को वहाँ उतरने के लिए प्रतीक्षा करने की आवश्यकता नहीं है, इसलिए आप वास्तव में डिस्क से टकराने की गति दंड को देखकर नहीं ।

यदि आप डिस्क ऑपरेशन के पूरा होने की प्रतीक्षा करना चाहते हैं, तो यह देखने के लिए कि कितना धीमा हो जाता है, कॉल करें sync()(अपने अजगर संस्करण पर कैसे भिन्न होता है, यहां देखें ) - आप अपनी डिस्क के लिए बस हजारों माइक्रोसेकंड देख रहे होंगे फ़ाइल को लिखने के लिए एक दो बार की तलाश करें (यह मानते हुए कि किसी तरह का तेज़ गति से लिखने वाला कैश नहीं है जैसे RAID कंट्रोलर में)।


हम अपने ब्लॉक उपकरणों की तलाश के समय के बारे में चिंता करना बंद कर देते हैं? :)
EEAA

5
@EEAA सभी SSDs, हर समय।

1
आप सही हैं: sync()डिस्क-लिखने का समय औसतन 74,000 माइक्रोसेकंड हो जाता है। ( flush()मैं अपने परीक्षण के एक भिन्नता में कर रहा था, यह नहीं किया।) तो मेरी व्याख्या है कि 500 ​​~ 640 माइक्रोसेकंड प्रति मेगाबाइट वास्तव में पाइप ओवरहेड समझ में आता है, धन्यवाद।
जिम पिवार्स्की 18
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.