2012-01-03 13 views
7

मेरे कार्यक्रम में मैं बड़ी संख्या में पुनरावृत्तियों के लिए एन-बॉडी सिस्टम अनुकरण कर रहा हूं। प्रत्येक पुनरावृत्ति के लिए मैं 6 एन निर्देशांक का एक सेट तैयार करता हूं जिसे मुझे फ़ाइल में जोड़ने की आवश्यकता होती है और फिर अगले पुनरावृत्ति को निष्पादित करने के लिए उपयोग किया जाता है। कोड सी ++ में लिखा गया है और वर्तमान में प्रत्येक पुनरावृत्ति पर बाइनरी प्रारूप में डेटा लिखने के लिए ofstream की विधि write() का उपयोग करता है।इसे उत्पादित करते समय डेटा लिखने का सबसे तेज़ तरीका

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

मैं उलझन में हूं क्योंकि मुझे वास्तविक समांतर प्रोग्रामिंग और निम्न स्तर की फ़ाइल I/O में कोई अनुभव नहीं है। मैं कुछ सार तकनीक है कि मैं मैं लागू कर सकता है की कल्पना के बारे में सोचा, के बाद से मैं यूनिक्स OSes के साथ आधुनिक (संभवतः मल्टी कोर) के लिए प्रोग्रामिंग मशीनों हूँ:

  • n पुनरावृत्तियों की मात्रा में फ़ाइल में डेटा लेखन (वहाँ लगते हैं कैसे वास्तव में एक बफर लागू करने के लिए इतना है कि धागे उचित रूप से सिंक्रनाइज़ किए जाते हैं, और ओवरलैप नहीं आगे बढ़ने के लिए बेहतर तरीके ...)
  • OpenMP (साथ कोड parallelizing होने के लिए?)
  • mmap (फ़ाइल आकार का उपयोग करते हुए किया जा सकता है विशाल, जीबी के क्रम में, क्या यह दृष्टिकोण पर्याप्त मजबूत है?)

हालांकि, मुझे नहीं पता कि उन्हें सर्वोत्तम रूप से कैसे कार्यान्वित किया जाए और उन्हें उचित तरीके से संयोजित किया जाए।

+0

आपका प्रश्न क्या है? –

+6

"मुझे लगता है कि प्रत्येक चक्र में गणना के परिणाम लिखने से जुड़ी विलंबता सॉफ्टवेयर के प्रदर्शन को धीमा कर देती है।" क्या आपको लगता है या आपने अपना कोड प्रोफाइल किया है? –

+0

क्या आपने यह सुनिश्चित करने के लिए कोड को प्रोफाइल किया है कि विलंबता के बारे में आपकी भावनाएं सही हैं? – Grizzly

उत्तर

3

बेशक प्रत्येक पुनरावृत्ति पर एक फ़ाइल में लिखना अक्षम है और संभवतः आपके कंप्यूटिंग को धीमा कर देता है। (अंगूठे के नियम के रूप में, आपके एक्टुअल मामले पर निर्भर करता है)

आपको producer ->consumer डिज़ाइन पैटर्न का उपयोग करना होगा। वे एक कन्वेयर बेल्ट की तरह कतार से जुड़े होंगे।

  • निर्माता जितना तेज़ हो सके उतना तेज़ उत्पादन करने की कोशिश करेगा, केवल उपभोक्ता इसे संभाल नहीं सकता है।
  • उपभोक्ता जितना तेज़ हो सके "उपभोग" करने का प्रयास करेगा।

दोनों को विभाजित करके, आप प्रदर्शन को अधिक आसानी से बढ़ा सकते हैं क्योंकि प्रत्येक प्रक्रिया सरल होती है और दूसरे से कम अंतर होता है।

  • निर्माता तेजी से होता है, तो आप उपभोक्ता सुधार करने के लिए, आपके मामले में सबसे अधिक संभावना हिस्सा द्वारा सबसे कारगर तरीका में फ़ाइल में लेखन, हिस्सा है (जैसा कि आपने कहा था) द्वारा की जरूरत है
  • उपभोक्ता तेजी से होता है, तो , आपको निर्माता को बेहतर बनाने की आवश्यकता है, जैसा कि आपने कहा था उतना ही समानांतर करके।

वहाँ कोई जरूरत दोनों का अनुकूलन है। केवल सबसे धीमी (बाधा) अनुकूलित करें।

व्यावहारिक रूप से, आप धागे और उनके बीच सिंक्रनाइज़ कतार का उपयोग करते हैं। कार्यान्वयन संकेतों के लिए, here देखें, खासकर §18.12 "निर्माता-उपभोक्ता पैटर्न"।

प्रवाह प्रबंधन के बारे में, आपको "अधिकतम कतार आकार" चुनकर और निर्माता (ओं) का इंतजार करके थोड़ी अधिक जटिलता जोड़नी होगी यदि कतार में पर्याप्त स्थान नहीं है। डेडलॉक्स से सावधान रहें, इसे ध्यान से कोड करें। (उस विकिपीडिया लिंक को मैंने इसके बारे में दिया)

नोट: बूस्ट थ्रेड का उपयोग करना एक अच्छा विचार है क्योंकि धागे बहुत पोर्टेबल नहीं हैं। (ठीक है, वे सी ++ 0x के बाद से हैं लेकिन सी ++ 0x उपलब्धता अभी तक अच्छी नहीं है)

+0

पर निर्भर करते हैं, लेकिन डेटा के आकार को देखते हुए, उस मामले को कैसे संभालना है जहां निर्माता इतनी तेज़ी से है कि यह कुछ ऐसा उत्पन्न करता है जो उपभोक्ता को डिस्क पर सहेजने से पहले स्मृति में संग्रहीत नहीं किया जा सकता है? –

+2

@ फ़ियाट लक्स ठीक है यदि आप अपने फाइल सिस्टम पर संग्रहीत डेटा से तेज़ी से डेटा का उत्पादन करते हैं तो आपके पास किसी भी सॉफ्टवेयर चाल से पूरी तरह स्वतंत्र है। यदि आपकी बैंडविड्थ बहुत छोटी है, तो जल्दी या बाद में आप बफर स्पेस से बाहर हो जाएंगे और फिर आपको उस मामले को किसी भी तरह से संभालना होगा। – Voo

+1

@ फ़ियाट्लक्स यही कारण है कि मैंने कहा "procducer ... केवल धीमा अगर उपभोक्ता इसे संभाल नहीं सकता है"। मैंने एक कार्यान्वयन उदाहरण + सुझाए गए सुधारों के लिए एक लिंक जोड़ने के लिए संपादित किया। अगर स्मृति पूरी हो जाती है तो आपको उत्पादकों को इंतजार करना होगा। – Offirmo

1

ऑपरेशन को दो स्वतंत्र प्रक्रियाओं में विभाजित करना बेहतर है: data-producing और file-writingData-producing पुनरावृत्ति-वार डेटा पास करने के लिए कुछ बफर का उपयोग करेगा, और file-writing लिखने के अनुरोधों को संग्रहीत करने के लिए कतार का उपयोग करेगा। फिर, data-producing सिर्फ एक लिखने का अनुरोध पोस्ट करेगा और आगे बढ़ेगा, जबकि file-writing पृष्ठभूमि में लेखन का सामना करेगा।

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

+0

आपको लगता है कि आप ओएस ब्लॉक कैश की तुलना में बफरिंग का बेहतर काम क्यों कर सकते हैं? –

+0

@SteveC क्योंकि कार्यान्वयन-निर्भर सुविधाओं पर भरोसा करने के बजाय निर्धारिती तरीके से एल्गोरिदम लागू करना बेहतर होता है। मेरा मतलब है, ब्लॉक कैश * अच्छा है, लेकिन यह विशिष्ट स्थिति में फिट हो सकता है या नहीं। यह पोर्टेबल नहीं हो सकता है, यह तेज़ नहीं हो सकता है, आदि, और ओपी वैसे भी विशिष्ट नहीं था :) – vines

+0

उस स्थिति में आपको बफरिंग की दो परतों से गुजरना नहीं चाहिए, लेकिन बस फाइल सिस्टम को बाईपास करें और लिखें कच्ची डिस्क यह "अधिक निर्धारक" है और आप इसे "विशिष्ट स्थिति में फिट कर सकते हैं"। निजी तौर पर, मुझे संदेह है कि आप फाइल सिस्टम लेखकों की तुलना में बेहतर काम कर सकते हैं। –

0

"mmap का उपयोग करना (फ़ाइल आकार बहुत बड़ा हो सकता है, GB का के आदेश पर, पर्याप्त इस दृष्टिकोण मजबूत है?)"

mmap लोड हो रहा है कार्यक्रमों, साझा पुस्तकालयों और के ओएस विधि है पृष्ठ/स्वैप फ़ाइल - यह किसी भी अन्य फ़ाइल I/O और आम तौर पर उच्च प्रदर्शन के रूप में मजबूत है।

लेकिन अधिकांश ओएस पर यह एक मैप किए गए फ़ाइल के आकार का विस्तार करने के दौरान खराब/कठिन/असंभव है। तो यदि आप डेटा के आकार को जानते हैं, या आप केवल पढ़ रहे हैं, तो यह बहुत अच्छा है। एक लॉग/डंप के लिए जो आप लगातार कम से कम जोड़ रहे हैं - जब तक कि आप कुछ अधिकतम आकार नहीं जानते।

+0

मुझे डेटा का आकार पता है, लेकिन 32 बिट सिस्टम के साथ कोई समस्या नहीं होगी यदि मेरे पास कुछ गीगाबाइट्स की फ़ाइल है? –

+0

@ फ़ियाट - यह mmap का बड़ा लाभ है। आप ऑफसेट्स के साथ फ़ाइल में कई दृश्यों को मैप कर सकते हैं ताकि आप फ़ाइल के किसी भी भाग तक पहुंचने के लिए विंडो का उपयोग कर सकें जितना बड़ा एफएस अनुमति देगा। विवरण आपके ओएस –

1

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

यह समाधान अभी भी अन्य उत्तरों में उल्लिखित निर्माता/उपभोक्ता समस्या से पीड़ित है, यदि आपका एल्गोरिदम डेटा लिखने से तेज़ी से उत्पादित कर रहा है, तो अंततः आप एल्गोरिदम और लिखने के बीच परिणामों को संग्रहीत करने के लिए स्मृति से बाहर हो जाएंगे , इसलिए आपको इसे आजमा देना होगा और देखें कि यह कैसे काम करता है।

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