2012-03-23 19 views
16

मुझे स्थानीय लिनक्स फाइल सिस्टम पर रहने वाली 10,000 फ़ाइलों को संसाधित करने के लिए कुछ कोड (किसी भी भाषा में) लिखने की आवश्यकता है। प्रत्येक फ़ाइल आकार में ~ 500 केबी है, और प्रत्येक के 4 केबी के निश्चित आकार के रिकॉर्ड होते हैं।कई छोटी फ़ाइलों को पढ़ने पर समय तलाशना

प्रति रिकॉर्ड प्रसंस्करण समय नगण्य है, और रिकॉर्ड को विभिन्न फ़ाइलों के भीतर और दोनों में, किसी भी क्रम में संसाधित किया जा सकता है।

कुछ भयानक कार्यान्वयन कुछ मनमानी क्रम में फ़ाइलों को एक-एक करके पढ़ा जाएगा। हालांकि, चूंकि मेरे डिस्क पढ़ने के लिए बहुत तेज़ हैं लेकिन खोजना धीमा है, यह लगभग निश्चित रूप से कोड उत्पन्न करेगा जो डिस्क की मांग से बंधे हैं।

क्या पढ़ने के लिए कोड करने का कोई तरीका है ताकि यह समय तलाशने के बजाय डिस्क थ्रूपुट से बाध्य हो?

पूछताछ की एक पंक्ति डिस्क पर मौजूद फाइलों का अनुमान लगाने का अनुमान लगाने और प्राप्त करने के लिए है, और इसे पढ़ने के अनुक्रम के लिए इसका उपयोग करें। हालांकि, मुझे यकीन नहीं है कि ऐसा करने के लिए एपीआई का उपयोग कैसे किया जा सकता है।

मैं निश्चित रूप से किसी भी अन्य विचारों के लिए खुला हूं।

फाइल सिस्टम ext4 है, लेकिन यह परक्राम्य है।

+2

एकाधिक फ़ाइलों का उपयोग क्यों करें? आप निश्चित रिकॉर्ड और समूह आकार के साथ केवल एक बड़ी फ़ाइल का उपयोग कर सकते हैं? – ydroneaud

+0

इन फ़ाइलों को कैसे संसाधित किया जाएगा? – Har

+0

@ydroneaud: मुझे कोई नियंत्रण नहीं है कि फाइलें कैसे बनाई जाती हैं, और उन्हें प्री-प्रोसेसिंग चरण के रूप में विलय करने से वास्तव में वही प्रश्न उठता है (यानी * एक सभ्य प्रदर्शन प्राप्त करने के लिए मर्ज के दौरान उन्हें किस क्रम में पढ़ा जाना चाहिए?) – NPE

उत्तर

6

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

+0

(+1) दिलचस्प विचार, धन्यवाद। – NPE

+0

Aio_read को फ़ाइल डिस्क्रिप्टर की आवश्यकता है। और यह संभवतः खुला() या पहला पठन() धीमा है। – wildplasser

+0

@Wildplasser: मैं देख सकता हूं कि 'ओपन' में निर्देशिका संरचना को कैसे चलाना धीमा हो सकता है, लेकिन क्या यह वास्तव में एक समस्या है यदि फाइल सीमित निर्देशिका में हैं? एक बार एक ही निर्देशिका में फ़ाइल खोले जाने के बाद, बाद की फ़ाइलों को जल्दी से खोलना चाहिए क्योंकि अधिकांश या सभी डिस्क डेटा को खोलने के लिए आवश्यक है, है ना? –

0

चूंकि संचालन समान हैं और डेटा स्वतंत्र हैं, इसलिए आप कई फ़ाइलों पर काम करने वाली नौकरियां सबमिट करने के लिए थ्रेड पूल का उपयोग करने का प्रयास कर सकते हैं (एक फ़ाइल हो सकती है)। फिर आप एक निष्क्रिय धागा एक ही नौकरी पूरा कर सकते हैं। यह निष्पादन के साथ आईओ संचालन ओवरलैप करने में मदद कर सकता है।

+0

प्रसंस्करण इतना आसान है कि इसे एक अनिवार्य समय की आवश्यकता होती है। इसलिए I/O के साथ इसे ओवरलैप करना दुख की बात नहीं होगी। – NPE

0

मूल प्रोग्राम को रखने का एक आसान तरीका होगा, लेकिन एक अतिरिक्त प्रक्रिया को फोर्क करें जिसमें फाइलों को प्रीफ़ेच करने की तुलना में कोई अन्य कार्य नहीं है, और डिस्क बफर कैश को प्राथमिकता दें। (एक यूनिक्स/लिनक्स सिस्टम डिस्क बफर के रूप में सभी "मुक्त" मेमोरी का उपयोग करता है)।

मुख्य कार्य कुछ फाइलें (दस कहें) रहेंगे। कठिन हिस्सा चीजों को सिंक्रनाइज़ करना होगा। एक पाइप इसे पूरा करने का स्पष्ट तरीका प्रतीत होता है।

अद्यतन: मुख्य प्रक्रिया के लिए

छद्म कोड:

    • worklist
    • अगर खाली गोटो 2 से फ़ाइल नाम से लाएं।
    • (शायद) एक कार्यकर्ता प्रक्रिया कांटा या थ्रेड कतार prefetch करने
    • ऐड आंतरिक कतार
    • में जोड़ने के लिए है, तो आंतरिक कतार गोटो पर XXX से कम आइटम 1
    • लाने आंतरिक कतार से फ़ाइल नाम
    • इसे संसाधित करें
    • गोटो 1

गुलाम प्रक्रियाओं के लिए:

  • कतार से लाने
  • खाली हो तो: कतार के लिए छोड़ दिया
  • प्रीफ़ेच फ़ाइल
  • पाश या छोड़ने

, एक संदेश कतार सबसे अधिक apropiate लगता है, क्योंकि यह संदेश सीमाओं को बनाए रखता है। एक और तरीका यह होगा कि प्रति बच्चे एक पाइप (कांटा() मामले में) या म्यूटेक्स (धागे का उपयोग करते समय) का उपयोग करें।

आपको अनुमानित seektime_per_file/processing_time_per_file कार्यकर्ता धागे/प्रक्रियाओं की आवश्यकता होगी।

एक सरलीकरण के रूप में: अगर फ़ाइलों की मांग की आवश्यकता नहीं है (केवल अनुक्रमिक अभिगम), गुलाम प्रक्रियाओं

dd if=name bs=500K 

के बराबर है, जो एक popen (में लपेटा जा सकता है से मिलकर सकता है) या एक पाइप + कांटा()।

+1

इस सेटअप में प्रीफ़ेचर खोजेगा, इसलिए फ़ाइलों को संसाधित करने के लिए आवश्यक समग्र समय में सुधार नहीं होगा। – NPE

+0

आप अधिक prefetchers का उपयोग कर सकते हैं, और उन्हें एक ही कमांड पाइप चूसने दें। – wildplasser

+0

मैं वास्तव में नहीं देखता कि यह डिस्क की तलाश में कैसे मदद करेगा। शायद आप विस्तृत कर सकते हैं? – NPE

1

क्या आप फ़ाइल संग्रहण के लिए एसएसडी का उपयोग करने की सलाह दे सकते हैं? जो खोज के समय को कम करना चाहिए क्योंकि आगे बढ़ने के लिए कोई सिर नहीं है।

+0

अच्छा विचार, लेकिन हाथ में समस्या के लिए निषिद्ध रूप से महंगा (जो मैंने अपने प्रश्न में उल्लिखित किया है वह संपूर्ण डेटासेट का एक छोटा सा अंश है)। – NPE

+0

हार्डवेयर और सॉफ्टवेयर दोनों में तंत्र हैं, जो एचडीडी के लिए एक छोटे से एसएसडी का उपयोग करते हैं। मैंने अभ्यास में किसी का भी उपयोग नहीं किया है, लेकिन मैंने कहीं एक बेंचमार्क देखा (निर्माता द्वारा नहीं) जहां उन्होंने कुछ mySQL वर्कलोड के लिए प्रदर्शन मापा और एचडीडी की तुलना में एसएसडी काफी छोटा था, भले ही ऐसे कैश काफी प्रभावी पाए। –

+0

@ MichałKosmulski: सच है, लेकिन एचडीडी से डेटा पढ़ने की समस्या बनी हुई है। – NPE

2

एक बहुत ही सरल दृष्टिकोण, हालांकि कोई परिणाम गारंटी नहीं है। कई फ़ाइलों को एक बार में खोलें जैसे आप कर सकते हैं और उनमें से सभी को एक साथ पढ़ सकते हैं - या तो धागे या एसिंक्रोनस I/O का उपयोग कर। इस प्रकार डिस्क शेड्यूलर जानता है कि आप क्या पढ़ते हैं और स्वयं की तलाश को कम कर सकते हैं। संपादित करें:वाइल्डप्लसर देखता है, समानांतर open() शायद थ्रेड का उपयोग करने योग्य है, async I/O नहीं।

विकल्प भारी उठाने का प्रयास करना है। दुर्भाग्यवश इसमें एक कठिन कदम शामिल है - फ़ाइलों को भौतिक ब्लॉक में मैपिंग प्राप्त करना। ऐसा करने के लिए कोई मानक इंटरफ़ेस नहीं है, आप शायद ext2fsprogs या कर्नेल एफएस ड्राइवर जैसे तर्क से निकालें। और इसमें एक घुड़सवार फाइल सिस्टम के अंतर्निहित भौतिक उपकरण को पढ़ना शामिल है, जिसे आप एक ही समय में लिख सकते हैं जब आप लगातार स्नैपशॉट प्राप्त करने का प्रयास कर रहे हैं।

एक बार जब आप भौतिक ब्लॉक प्राप्त कर लेते हैं, तो बस उन्हें ऑर्डर करें, फ़ाइल ऑफसेट पर मैपिंग को वापस ले जाएं और भौतिक ब्लॉक ऑर्डर में रीड निष्पादित करें।

+0

यह समग्र प्रक्रिया को तेज नहीं करेगा। यह खुले() या पहले ब्लॉक का पठन है जो प्रक्रिया को अवरुद्ध करता है। – wildplasser

+0

(+1) दो विचारों के लिए धन्यवाद और e2fsprogs के लिंक के लिए धन्यवाद। – NPE

+0

@ विल्डप्लसर आपने समांतर में सभी 'खुले()' कॉल शेड्यूल किए हैं, फिर शेड्यूलर को प्रत्येक फ़ाइल के पहले ब्लॉक के बीच खोज समय अनुकूलित करने का मौका है। –

संबंधित मुद्दे