2009-10-28 20 views
18

मैं निम्नलिखित प्रोग्राम को चलाने की कोशिश कर रहा हूं, जो डिग्री के बहुपदों की जड़ों की गणना करता है जो गुणांक के साथ केवल +1 या -1 के साथ होता है, और फिर इसे फ़ाइलों में संग्रहीत करता है।मैथमैटिका मेमोरी से बाहर चल रहा है

d = 20; n = 18000; 
f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}]; 

यहां एफ [z, i] बाइनरी में गिनती के साथ प्लस या माइनस संकेतों के साथ z में बहुपद देता है। d कहना = 2, हम होता

च [z, 1] = -z - जेड - 1
च [z, 2] = -z - जेड + 1
च [ z, 3] = -z + z - 1
च [z, 4] = -z + z + 1

DistributeDefinitions[d, n, f] 

ParallelDo[ 
      Do[ 
        root = N[Root[f[z, i], j]]; 
        {a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2]; 
      {i, 1, 2^d}], 
{j, 1, d}] 

मैं पढ़ जानते हैं कि यह शायद बहुत सुखद नहीं है , लेकिन यह वैसे भी अपेक्षाकृत छोटा है। मैं प्रासंगिक भागों में कटौती करने की कोशिश करता, लेकिन यहां मुझे वास्तव में कोई संकेत नहीं है कि समस्या क्या है। मैं f [z, i] की सभी जड़ों की गणना कर रहा हूं, और उसके बाद उन्हें एन एन ग्रिड द्वारा एन में एक बिंदु से मेल खाने के लिए, और विभिन्न डेटा में उस डेटा को सहेजने के लिए बस उन्हें गोल करें।

किसी कारण से, मैथमैटिका में स्मृति उपयोग तब तक गिर जाता है जब तक यह सभी मेमोरी (इस मशीन पर 6 जीबी) भरता नहीं है; तो गणना अत्यंत धीरे-धीरे जारी है; यह क्यों है?

मुझे यकीन नहीं है कि यहां मेमोरी का उपयोग क्या कर रहा है - मेरा एकमात्र अनुमान स्मृति का उपयोग करने वाली फ़ाइलों की धारा थी, लेकिन ऐसा नहीं है: मैंने 2 जीबी फाइलों में डेटा जोड़ने की कोशिश की और इसके लिए कोई ध्यान देने योग्य स्मृति उपयोग नहीं था । यहां गणित की बड़ी मात्रा में स्मृति का उपयोग करने का कोई कारण नहीं है।

डी के छोटे मानों के लिए (उदाहरण के लिए 15), व्यवहार निम्न है: मेरे पास 4 कर्नेल चल रहे हैं। चूंकि वे सभी समांतर डीओ लूप (प्रत्येक एक समय में जम्मू का मूल्य कर रहे हैं) के माध्यम से चलाते हैं, स्मृति उपयोग तब तक बढ़ता है जब तक कि वे सभी उस लूप के माध्यम से एक बार नहीं जाते। फिर अगली बार वे उस लूप के माध्यम से जाते हैं, स्मृति उपयोग बिल्कुल बढ़ता नहीं है। गणना अंततः समाप्त होती है और सब कुछ ठीक है।

इसके अलावा, काफी महत्वपूर्ण बात यह है कि गणना बंद होने के बाद, स्मृति उपयोग वापस नहीं जाता है। यदि मैं एक और गणना शुरू करता हूं, तो निम्न होता है:

- अगर पिछली गणना तब भी रुक गई जब स्मृति उपयोग अभी भी बढ़ रहा था, यह बढ़ता जा रहा है (मूल रूप से एक ही बिंदु पर पहुंचने में कुछ समय लग सकता है गणना में)।

- अगर पिछली गणना रोक दी गई थी जब स्मृति उपयोग बढ़ रहा था, तो यह आगे नहीं बढ़ता है।

संपादित करें: यह समस्या एफ की सापेक्ष जटिलता से आती है - इसे कुछ आसान बहुपद में बदलना इस मुद्दे को ठीक करने लगता है। मैंने सोचा कि समस्या यह हो सकती है कि मैथमैटिका मुझे f के विशिष्ट f के लिए f [z, i] याद करता है, लेकिन f [z, i]: = सेटिंग। एफ [z, i] की जड़ की गणना करने के बाद ही शिकायत है कि असाइनमेंट पहले स्थान पर मौजूद नहीं था, और स्मृति अभी भी उपयोग की जा रही है।

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

+0

क्या आपने इस एल्गोरिदम को छोटे, या यहां तक ​​कि व्यक्तिगत डी मानों के साथ चलाने का प्रयास किया है? –

+0

मैंने अभी एक पैराग्राफ जोड़ा जो वर्णन करता है कि छोटे डी के लिए क्या होता है। –

+0

क्या होता है जब आप स्ट्रीम खोलने, लिखने और स्ट्रीम को बंद किए बिना प्रोग्राम चलाते हैं (यानी, बिना किसी I/O के)? – Pillsy

उत्तर

11

ओच, यह एक बुरा है।

क्या हो रहा है कि N भविष्य की गणना को तेज करने के लिए परिणामों की कैशिंग करेगा यदि आपको दोबारा आवश्यकता हो। कभी-कभी यह वही है जो आप चाहते हैं, लेकिन कभी-कभी यह दुनिया को तोड़ देता है। सौभाग्य से, आपके पास कुछ विकल्प हैं। एक ClearSystemCache कमांड का उपयोग करना है, जो टिन पर जो कुछ भी कहा गया है, वह करता है। थोड़ी देर के लिए आपके अन-समांतर लूप को चलाने के बाद (ऊबने से पहले और गणना को निरस्त करने से पहले), MemoryInUse ने ~ 160 एमआईबी उपयोग में बताया। ClearSystemCache का उपयोग करके लगभग 14 एमआईबी तक पहुंच गया।

प्रोग्रामिंग के रूप में ClearSystemCache पर कॉल करने के बजाय आपको एक चीज देखना चाहिए, कैशिंग व्यवहार को बदलने के लिए SetSystemOptions का उपयोग करना है। संभावनाएं क्या हैं, यह देखने के लिए आपको SystemOptions["CacheOptions"] पर एक नज़र डालना चाहिए।

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

+0

हम्म, मुझे आपके परिणामों की प्रतिलिपि बनाने में परेशानी हो रही है। फिलहाल, दो समस्याएं होती हैं: अनन्य संस्करण में, जब मैं ClearSystemCache को कॉल करता हूं, तो MemoryInUse रिपोर्ट करता है कि उपयोग में स्मृति वापस आ गई है, लेकिन कार्य प्रबंधक कर्नेल को अभी भी उतनी मेमोरी का उपयोग करता है। दूसरा, समांतर मोड में, मुझे व्यक्तिगत कर्नेल के कैश को साफ़ करने का विकल्प नहीं मिल रहा है। लेकिन आपको सटीक कारण मिल गया था, अब यह पता लगाने का मामला है कि इसका इलाज कैसे किया जाए। –

+0

कैशऑप्शन के साथ मेसिंग या तो उपयोगी साबित नहीं हुआ - मैंने सबकुछ गलत और अधिकतम बाइट आकार 0 पर सेट किया है और इससे कोई फर्क नहीं पड़ता (समानांतर संस्करण के लिए और समानांतर संस्करण में कोई अंतर नहीं है)। –

+0

ठीक है, साफ़ सिस्टसिस्टम कैश वास्तव में काम करता है; किसी कारण से यह पहली बार काम नहीं करता था, लेकिन अब यह काम करता है। यह समानांतर संस्करण में भी काम करता है। धन्यवाद! –

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