2014-10-19 7 views
5

मैं एक सेल, Data, यह तीन डबल सरणियों,केवल एक मैट्रिक्स द्वारा स्मृति समाप्त स्थानांतरित

Data = 

[74003x253 double] [8061x253 double] [7241x253 double] 

मैं एक पाश का उपयोग कर रहा है, इन सरणियों पढ़ सकते हैं और कुछ कार्य करने के लिए शामिल है

for ii = 1 : 3 
    D = Data {ii} ; 
    m = mean (D') ; 
    // rest of the code 
end 

कौन सा mean के लिए एक चेतावनी हो जाता है और कहता है:

अलग मंद का उपयोग कर विचार मतलब

के लिए ension इनपुट तर्क लेकिन जब मैं इसे करने के लिए, बदलने

for ii = 1 : 3 
    D = Data {ii}' ; 
    m = mean (D) ; 
    // rest of the code 
end 

मैं स्मृति त्रुटि से मिलता है।

दो कोड की तुलना में, क्या कोई समझा सकता है कि क्या होता है?

ऐसा लगता है कि मुझे केवल जटिल संयोग ट्रांसफर (मेरा डेटा वास्तविक मूल्यवान है) के साथ त्रुटि मिलती है।

+0

कौन सा पुनरावृत्ति करता है _ स्मृति त्रुटि_ के बाहर होता है? क्या आप विफलता से पहले 'ii' के मूल्य बता सकते हैं? – user502144

+0

@ user502144, असल में, स्मृति त्रुटि _ _ लाइन का उल्लेख नहीं करता है (मैंने त्रुटि के लिए इसका उल्लेख करने में गलती की है, जिसे मैंने सही किया है)। हालांकि, इन दो कोडों में केवल एक संक्रमण परिवर्तन के साथ मैं त्रुटि को दूर कर सकता हूं। – Rashid

+0

किसी के लिए जटिल संख्याओं के साथ कुछ भी नहीं है - यह matrices को स्थानांतरित करता है जिसका अर्थ है कि इसे एक प्रतिलिपि बनाने की आवश्यकता है (अतिरिक्त रैम की आवश्यकता है)। मेरा अनुमान है, चूंकि मैटलैब समय संकलक में बहुत उन्नत का उपयोग करता है, यह पहले मामलों को पहचानता है और इसे 'माध्य (डी, 2)' के साथ सही ढंग से बदल देता है। – bdecaf

उत्तर

8

n के लिए मतलब लेने के लिए:।। वें आयाम यह संभव उपयोग mean(D,n) के रूप में पहले ही कहा गया के बारे में है मेमोरी खपत, मैंने विंडोज रिसोर्सेज मैनेजर के साथ कुछ परीक्षणों की निगरानी की। आउटपुट की उम्मीद थी।

ऑपरेशन करते समय D=Data{ii} केवल न्यूनतम मेमोरी खाई जाती है क्योंकि मैटलैब एक पॉइंटर कॉपी करने से अधिक नहीं करता है। हालांकि, जब एक ट्रांसपोज़र, मैटलैब को मैट्रिक्स डी को स्टोर करने के लिए अधिक मेमोरी आवंटित करने की आवश्यकता होती है, जिसका मतलब है कि स्मृति खपत बढ़ जाती है।

हालांकि, यह पूरी तरह से स्मृति ओवरफ्लो का कारण नहीं बनता है, क्योंकि दोनों मामलों में स्थानांतरण किया जाता है।

केस 1

अलग में D = Data{ii}';

केस 2 में

D = Data {ii}; m = mean(D');

अंतर में मामले 2 matlab केवल की अस्थायी प्रतिलिपि बनाता है वह यह है कि Data{ii}' जो वर्कस्पेस में संग्रहीत नहीं है। आवंटित स्मृति दोनों मामलों में समान है, लेकिन मामले में 1Data{ii}'D में संग्रहीत है। जब स्मृति बाद में बढ़ जाती है तो यह स्मृति मेमोफ़्लो का कारण बन सकती है।

D की स्मृति खपत खराब नहीं है (< 200 एमबी), लेकिन अनुमान यह है कि स्मृति पहले से ही अधिक हो गई है और यह स्मृति ओवरफ्लो देने के लिए पर्याप्त था।

for i = 1 : length(Data) 
    % as chappjc recommends this is an excellent solution 
    m = mean(Data{i}, 2); 
end 

या यदि आप पक्षांतरित चाहते हैं और आप जानते हैं कि डेटा वास्तविक (नहीं जटिल)

for i = 1 : length(Data) 
    m = mean(Data{i}.'); 
end 

नोट है, पक्षांतरित से पहले डॉट:

6

चेतावनी संदेश का अर्थ है कि बजाय,

m = mean (D') ; 

आपको क्या करना चाहिए:

m = mean (D,2); 

यह दूसरी आयाम में मतलब ले जाएगा एक स्तंभ वेक्टर के साथ size(D,1) की लंबाई छोड़ने ।

मुझे नहीं पता कि जब आप D = Data {ii}' करते हैं तो आपको केवल स्मृति त्रुटि से बाहर क्यों मिलता है। शायद यह आप mean के पक्ष में यह है, जब (m = mean (D') ; JIT किसी भी तरह का अनुकूलन और आप व्यर्थ स्मृति को बचाने के लिए प्रबंधन करता है becauase है

+0

मुझे 'माध्य (डी, 2) ', धन्यवाद के बारे में पता नहीं था। और स्मृति त्रुटि के लिए, यह वास्तव में अजीब है। – Rashid

+2

@ कमल: जब भी MATLAB प्रलेखन पढ़ते हैं, वाक्यांश "... पहले गैर-सिंगलटन आयाम पर चलता है" का अर्थ है कि ऑपरेशन एक ["कमी, या गुना, या बहु-इनपुट एकल-आउटपुट ऑपरेटर"] है (http: //en.wikipedia.org/wiki/Fold_(higher-order_function)), और ऑपरेटर "पहले गैर-सिंगलटन आयाम" से ली गई तत्वों को एक साथ समूहित करेगा। – rwong

+2

अगर मुझे लगता है कि, 'डी = डेटा {i}' वास्तव में 'माध्य (डी) 'को पास करने से पहले डेटा की एक पूर्ण ट्रांसपोज़ प्रतिलिपि बनाता है। दूसरी तरफ, 'डी = डेटा {i}' पहले साझा-डेटा प्रतिलिपि बनाता है (आलसी प्रतिलिपि पर विचार करें), फिर कॉल 'माध्य (डी') 'को "अस्थायी" अभिव्यक्ति पारित की जाती है, जो कि है जेआईटी ऑप्टिमाइज़ेशन के लिए एक संभावित लक्ष्य (यह मानकर कि 'माध्य' एक नई प्रतिलिपि में मैट्रिक्स को वास्तव में ट्रांसपोज़ किए बिना परिणाम की गणना कर सकता है, यह उचित लंबाई के चरणों में मौजूदा मैट्रिक्स को पार करने के लिए पर्याप्त है) – Amro

1

यहाँ ऐसा करने के कुछ तरीके हैं ।

या, सब एक साथ

m = cellfun(@(d) mean(d, 2), Data, 'uniformoutput', false); 

जब आप ऐसा करेंगे पाश छोड़:

D = Data{i}' 

मैटलैब अपने डेटा की एक नई प्रतिलिपि बनाएगा। यह 74003x253 युगल आवंटित करेगा, जो लगभग 150 एमबी है। जैसा कि पैट्रिक ने बताया, यह देखते हुए कि आपके पास अन्य डेटा हो सकता है, आप आसानी से अनुमत स्मृति आवंटन उपयोग (विशेष रूप से 32-बिट मशीन पर) से अधिक हो सकते हैं।

आप स्मृति समस्याओं के साथ चला रहे हैं, संगणना नहीं संवेदनशील, आप एकल परिशुद्धता के बजाय डबल की, यानी उपयोग करने पर विचार कर सकते हैं:

data{i} = single(data{i}); 

आदर्श रूप में, आप आवंटन के बिंदु पर एक सटीक क्या करना चाहते हैं अनावश्यक नए आवंटन और प्रतियों से बचने के लिए।

शुभकामनाएं।

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