2009-06-18 17 views
5

चलाते समय डेटा को डिस्क में सहेजने का कुशल तरीका मैं वैज्ञानिक सॉफ्टवेयर के एक टुकड़े पर काम कर रहा हूं जो बहुत सीपीयू-गहन (इसकी प्रो बाध्य) है, लेकिन इसे डिस्क पर डेटा को अक्सर लिखना होगा (i/ओ बाध्य)।कम्प्यूटेशनल गहन कार्य

मैं इस (ओपनएमपी) के समानांतरता जोड़ रहा हूं और मैं सोच रहा हूं कि लेखन-से-डिस्क आवश्यकताओं को हल करने का सबसे अच्छा तरीका क्या है। सिमुलेशन को एचडीडी पर इंतजार करना चाहिए (जो अब यह कर रहा है)।

मैं इसके लिए 'सर्वश्रेष्ठ अभ्यास' की तलाश में हूं, और गति वह है जो मुझे सबसे ज्यादा पसंद है (ये काफी लंबे सिमुलेशन हो सकते हैं)।

धन्यवाद ~ एलेक्स

पहले विचार:

एक अलग प्रक्रिया होने डिस्क के लिए वास्तविक लेखन ऐसा सिमुलेशन दो प्रक्रियाओं है: एक सीपीयू बाध्य (सिमुलेशन) है और एक आईओ बाध्य है (फाइल लिखना)। यह जटिल लगता है।

संभवतः एक पाइप/बफर? मैं इनके लिए नया हूं, इसलिए शायद यह एक संभावित समाधान हो सकता है।

उत्तर

2

आप अपने कार्यक्रम के लिए OpenMP को लागू है, तो यह फाइल करने के लिए बचाने के लिए समानांतर अनुभाग से #pragma omp एकल या #pragma omp मास्टर उपयोग करने के लिए बेहतर है। ये pragmas केवल एक धागा कुछ निष्पादित करने की अनुमति देता है। तो, आप कोड निम्नलिखित के रूप में देख सकते हैं:

#pragma omp parallel 
{ 
    // Calculating the first part 
    Calculate(); 

    // Using barrier to wait all threads 
    #pragma omp barrier 

    #pragma omp master 
    SaveFirstPartOfResults(); 

    // Calculate the second part 
    Calculate2(); 

    #pragma omp barrier 

    #pragma omp master 
    SaveSecondPart(); 

    Calculate3(); 

    // ... and so on 
} 

यहाँ धागे की टीम गणना करना होगा, लेकिन केवल एकल थ्रेड डिस्क के लिए परिणाम बचत होगी।

यह सॉफ्टवेयर पाइपलाइन की तरह दिखता है। मेरा सुझाव है कि आप इंटेल थ्रेडिंग बिल्डिंग ब्लॉक लाइब्रेरी से टीबीबी :: पाइपलाइन पैटर्न पर विचार करें। मैं आपको http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25 पर सॉफ़्टवेयर पाइपलाइनों पर ट्यूटोरियल में देख सकता हूं। कृपया अनुच्छेद 4.2 पढ़ें। उन्होंने समस्या हल की: ड्राइव से पढ़ने के लिए एक धागा, दूसरा स्ट्रिंग पढ़ने की प्रक्रिया को संसाधित करने के लिए, ड्राइव करने के लिए तीसरा एक।

5

मैं कहूंगा कि डेटा को बचाने के लिए एक अलग थ्रेड को बढ़ाने का सबसे अच्छा तरीका होगा, पूरी तरह से नई प्रक्रिया नहीं; एक नई प्रक्रिया के साथ, आप प्रक्रिया सीमा में सहेजे जाने वाले डेटा को संवाद करने की परेशानी चलाते हैं, जो कठिनाइयों का एक नया सेट पेश करता है।

0

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

1

चूंकि आप सीपीयू और आईओ बाध्य हैं: मुझे अनुमान लगाएं: अभी भी बहुत सारी मेमोरी उपलब्ध है, है ना?

यदि ऐसा है तो आपको डेटा को बफर करना चाहिए जिसे स्मृति में डिस्क पर एक निश्चित विस्तार के लिए लिखा जाना चाहिए। डेटा के विशाल भाग लिखना आमतौर पर छोटे टुकड़े लिखने से बहुत तेज होता है।

लेखन के लिए: मेमोरी मैप किए गए IO का उपयोग करने पर विचार करें। यह थोड़ी देर के बाद से मैंने बेंचमार्क किया है, लेकिन आखिरी बार मैंने यह काफी तेज था।

इसके अलावा आप हमेशा सीपीयू बनाम आईओ का व्यापार कर सकते हैं। मुझे लगता है कि आप वर्तमान में कुछ प्रकार के कच्चे, असम्पीडित डेटा के रूप में डेटा लिख ​​रहे हैं, है ना? यदि आप डेटा की मात्रा को कम करने के लिए एक सरल संपीड़न योजना का उपयोग करते हैं तो आपको कुछ आईओ प्रदर्शन मिल सकता है। ZLIB लाइब्रेरी सबसे कम संपीड़न स्तर पर बहुत तेजी से काम करने और संपीड़ित करने के लिए बहुत आसान है। यह आपके डेटा की प्रकृति पर निर्भर करता है, लेकिन यदि इसमें बहुत अधिक अनावश्यकता है तो भी एक बहुत क्रूड संपीड़न एल्गोरिदम आईओ बाध्य समस्या को खत्म कर सकता है।

3

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

समस्या यह है कि वास्तव में आपका सिमुलेशन चक्र तब तक पूरा नहीं होता जब तक कि परिणाम न हो जाएं।

दूसरी बात जो मेरे साथ होती है वह गैर-अवरुद्ध I/O का उपयोग करना है।जब भी सिम को लिखने की आवश्यकता होती है, तो इसे गैर-अवरुद्ध I/O के माध्यम से ऐसा करना चाहिए। लिखने की अगली आवश्यकता पर, यह नया शुरू करने से पहले पिछले आई/ओ ऑपरेशन (संभवतः एक छोटे से इंतजार कर रहा है) के परिणाम उठा सकता है। यह सिमुलेशन को I/O के साथ समानांतर में जितना संभव हो सके सिमुलेशन को लेखन से बहुत दूर जाने के बिना चल रहा है।

पहला समाधान बेहतर होगा यदि सिमुलेशन प्रोसेसिंग चक्र भिन्न होता है (कभी-कभी लिखने के समय से छोटा होता है, कभी-कभी लंबा) क्योंकि औसतन लिखने से सिम के साथ रहना पड़ सकता है।

यदि प्रसंस्करण चक्र हमेशा (या लगभग हमेशा) लिखने के समय से छोटा होने जा रहा है तो आप पाइप से परेशान नहीं हो सकते हैं और केवल गैर-अवरुद्ध I/O का उपयोग कर सकते हैं, क्योंकि यदि आप पाइप का उपयोग करते हैं यह अंततः भर जाएगा और सिम I/O पर भी लटका दिया जाएगा।

+0

मुझे लगता है कि 1-तरफा पाइप जिस तरह से मैं जाऊंगा। मुझे नहीं लगता कि मैं बहुत बुरी तरह अवरुद्ध करने के मुद्दे में भाग जाऊंगा; डेटा उत्पन्न होने के बहुत सारे नहीं हैं, मैं बस धागे को अलग करना चाहता था। यदि मैं इतना डेटा उत्पन्न कर रहा था, तो मैं पुनर्विचार करता हूं कि वास्तव में कितना रखा जाना चाहिए। – machinaut

0

अपने एप्लिकेशन को दो धागे, एक सीपीयू के लिए और एक हार्ड डिस्क के लिए बनाएं।

सीपीयू धागा धक्का एक कतार जो हार्ड डिस्क धागा फिर डेटा में आता है के रूप में से खींचती में पूरा डेटा है।

इस तरह सीपीयू सिर्फ डेटा से छुटकारा और किसी और यह और कड़ी संभाल करने देता हो जाता है ड्राइव सिर्फ धैर्यपूर्वक अपनी कतार में किसी भी डेटा के लिए इंतजार कर रहा है।

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

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