बड़े डेटा सेट के साथ कम्प्यूटेशनल समस्याओं के लिए I / O रणनीतियाँ?


15

मेरा शोध समूह आणविक गतिशीलता पर केंद्रित है, जो स्पष्ट रूप से एक प्रक्षेपवक्र के हिस्से के रूप में डेटा के गीगाबाइट्स उत्पन्न कर सकता है, जिसका विश्लेषण किया जाना चाहिए।

डेटा सेट में सहसंबंधों को शामिल करने से जुड़ी कई समस्याएं, जिसका अर्थ है कि हमें अधिक अनुक्रमिक दृष्टिकोण का उपयोग करने के बजाय, स्मृति में बड़ी मात्रा में डेटा का ट्रैक रखने और उनका विश्लेषण करने की आवश्यकता है।

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

कुछ अतिरिक्त नोट:

  • हम मुख्य रूप से "ऑन-लाइन" टूल्स के बजाय पोस्ट-प्रोसेसिंग के लिए स्क्रिप्टिंग टूल की तलाश कर रहे हैं - इसलिए पायथन का उपयोग।

  • डी=16लिमΔटी(एक्स(टी+Δटी)-एक्स(टी))2

जवाबों:


6

मैं मान रहा हूं कि आपका प्रश्न इस अवलोकन से आया है कि I / O आपके संपूर्ण विश्लेषण में एक महत्वपूर्ण ओवरहेड का कारण बनता है। उस स्थिति में, आप गणना के साथ I / O को ओवरलैप करने का प्रयास कर सकते हैं।

एक सफल दृष्टिकोण इस बात पर निर्भर करता है कि आप डेटा का उपयोग कैसे करते हैं, और उस डेटा पर आपके द्वारा की जाने वाली गणना। यदि आप एक पैटर्न की पहचान कर सकते हैं, या डेटा के विभिन्न क्षेत्रों तक पहुंच पहले से ज्ञात है, तो आप "वर्तमान चंक्स" को संसाधित करते समय पृष्ठभूमि में डेटा के "अगले विखंडू" को प्रीफ़ैच करने का प्रयास कर सकते हैं।

एक सरल उदाहरण के रूप में, यदि आप केवल एक बार अपनी फाइल को पार करते हैं और प्रत्येक पंक्ति या लाइनों के सेट को संसाधित करते हैं, तो आप स्ट्रीम को लाइनों (या एमबी) में विभाजित कर सकते हैं। फिर, विखंडू पर प्रत्येक पुनरावृत्ति पर, आप chunk i + 1 लोड कर सकते हैं जबकि chunk i।

आपकी स्थिति अधिक जटिल हो सकती है और इसमें अधिक शामिल समाधानों की आवश्यकता होती है। किसी भी स्थिति में, विचार पृष्ठभूमि में I / O निष्पादित करने का है, जबकि प्रोसेसर के पास काम करने के लिए कुछ डेटा है। यदि आप अपनी विशिष्ट समस्या के बारे में अधिक जानकारी देते हैं, तो हम इस पर गहराई से विचार कर सकते हैं;)

---- अधिक विवरण देने के बाद विस्तारित संस्करण ----

मुझे यकीन नहीं है कि मैं संकेतन को समझता हूं, लेकिन ठीक है, जैसा कि आपने कहा, विचार एक सभी के लिए अंतःक्रिया है। आप यह भी उल्लेख करते हैं कि डेटा रैम में फिट हो सकता है। फिर, मैं सभी डेटा लोड करने के लिए समय और माप प्रदर्शन करने के लिए समय को मापने के द्वारा शुरू करूंगा। अभी,

  • यदि I / O का प्रतिशत कम है (जैसे आप ओवरहेड की परवाह नहीं करते हैं, तो जो कुछ भी है: 0.5%, 2%, 5%, ...), तो बस सरल दृष्टिकोण का उपयोग करें: डेटा लोड करें एक बार, और गणना। आप अपने शोध के अधिक दिलचस्प पहलुओं के लिए समय बचाएंगे।

  • यदि आप ओवरहेड बर्दाश्त नहीं कर सकते हैं तो आप पेड्रो को सुझाव देना चाहते हैं। ध्यान रखें कि एरन अहमदिया ने क्या उल्लेख किया है, और पूर्ण कार्यान्वयन के लिए जाने से पहले इसका परीक्षण करें।

  • n2n

    लोड chunk1 और chunk2
    विखंडू के लिए मैं = 1 से एन
        अतुल्यकालिक रूप से chunk i + 1 लोड करें
        j = i + 1 से n में विखंडू के लिए
            अतुल्यकालिक रूप से chunk j + 1 लोड करें
            विखंडू के साथ गणना i, j (* पहली पुनरावृत्ति के लिए, ये प्रीलोडेड विखंडू 1 और 2 * हैं)

नोट: यह त्वरित और गंदे छद्म कोड है, किसी को सूचकांकों को समायोजित करने की आवश्यकता होगी।

इसे लागू करने के लिए, तथाकथित डबल-बफ़रिंग का उपयोग करना आम है । मोटे तौर पर बोलना: स्मृति को दो कार्यक्षेत्रों में विभाजित करना; जबकि डेटा को कार्यक्षेत्र 1 में पृष्ठभूमि में लोड किया जा रहा है, प्रोसेसर कार्यक्षेत्र 2 में डेटा के साथ गणना कर रहा है। प्रत्येक पुनरावृत्ति पर, भूमिका का आदान-प्रदान करें।

मुझे खेद है कि मैं अभी एक अच्छे संदर्भ के साथ नहीं आ सकता।

[1] एक आउट-ऑफ-कोर एल्गोरिथ्म डिस्क पर रहने वाले डेटा के साथ (कुशलतापूर्वक) सौदा करने के लिए कुछ तंत्र को शामिल करता है। इन्हें इन-कोर ("इन-रैम") के विपरीत आउट-ऑफ-कोर कहा जाता है।


7

मुझे पहले भी इसी तरह की समस्याओं से जूझना पड़ा है, और मेरा पसंदीदा समाधान मेमोरी-मैप्ड I / O का उपयोग करना है , हालांकि सी में ...

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

एक त्वरित Google खोज मुझे बताती है कि यह पायथन: 16.7 के लिए भी उपलब्ध है एमएमएपी - मेमोरी-मैप्ड फ़ाइल समर्थन , लेकिन मुझे यह बताने के लिए पर्याप्त नहीं है कि यह बताने के लिए कि क्या वास्तव में एक ही बात है।


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

1

शायद आप अपनी फ़ाइल I / O सेक्शन में Cython का उपयोग कर सकते हैं और इस भाग को C कोड में बदल सकते हैं?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.