2017-01-30 4 views
6

मैं कुछ कोड चला रहा हूं, जिसमें से एक हिस्सा एक बाइनरी फ़ाइल से बड़ी 1 डी numpy सरणी में लोड करता है, और फिर numpy.where() विधि का उपयोग करके सरणी को बदल देता है।पाइथन यादृच्छिक रूप से 0% CPU उपयोग तक गिर जाता है, जिससे कोड को "लटका" होता है, जब बड़े numpy arrays को संभाला जाता है?

यहाँ कोड में प्रदर्शन के संचालन का एक उदाहरण है:

import numpy as np 
num = 2048 
threshold = 0.5 

with open(file, 'rb') as f: 
    arr = np.fromfile(f, dtype=np.float32, count=num**3) 
    arr *= threshold 

arr = np.where(arr >= 1.0, 1.0, arr) 
vol_avg = np.sum(arr)/(num**3) 

# both arr and vol_avg needed later 

मैं इस में कई बार (एक नि: शुल्क मशीन पर, जिसका अर्थ है कोई अन्य बाधा CPU या स्मृति उपयोग) कोई समस्या नहीं के साथ समाप्त हो गया है। लेकिन हाल ही में मैंने देखा है कि कभी-कभी कोड एक विस्तारित अवधि के लिए लटकता है, जिससे रनटाइम लंबे समय तक परिमाण का क्रम बना देता है। इन अवसरों पर मैं% CPU और मेमोरी उपयोग (gnome सिस्टम मॉनीटर का उपयोग करके) की निगरानी कर रहा हूं, और पाया कि पायथन का CPU उपयोग 0% तक गिर जाता है।

उपरोक्त संचालन के बीच मूल प्रिंटों का उपयोग डीबग करने के लिए करते हुए, यह मनमाने ढंग से प्रतीत होता है कि किस ऑपरेशन को रोकना (यानी खुला(), np.fromfile(), np.where() प्रत्येक अलग से लटका हुआ है एक यादृच्छिक दौड़ पर)। ऐसा लगता है कि मुझे यादृच्छिक रूप से थ्रॉटल किया जा रहा है, क्योंकि अन्य रनों पर कोई लटक नहीं है।

मैंने कचरा संग्रह या this question जैसी चीजों पर विचार किया है, लेकिन मुझे मेरी समस्या का कोई स्पष्ट संबंध नहीं दिख रहा है (उदाहरण के लिए कीस्ट्रोक का कोई प्रभाव नहीं पड़ता है)।

आगे नोट्स: बाइनरी फ़ाइल 32 जीबी है, मशीन (चलने वाले लिनक्स) में 256 जीबी मेमोरी है। मैं एक एसएसएच सत्र के माध्यम से, इस कोड को दूरस्थ रूप से चला रहा हूं।

संपादित करें: यह आकस्मिक हो सकता है, लेकिन मैंने देखा है कि अगर मशीन को अभी रिबूट किया गया है तो कोड चलाने पर कोई लटका नहीं है। ऐसा लगता है कि वे कुछ रनों के बाद, या कम से कम सिस्टम के अन्य उपयोग के बाद होने लगते हैं।

+0

मुझे सच में नहीं लगता कि यह मामला है, लेकिन क्या आपके gnome sys प्रक्रिया के बजाए धागे की निगरानी करने की निगरानी कर रहे हैं? मेरा मानना ​​है कि numpy भारी कंप्यूटेशंस करने के लिए एक नया धागा फोर्क, लेकिन यह एक ही प्रक्रिया समूह के तहत होना चाहिए। तो फिर मैं पूरी तरह से गलत हो सकता है – Aaron

+0

तो स्मृति उपयोग समस्या नहीं है, या क्या आप कभी-कभी पाइथन लटकते समय पेजिंग देख सकते हैं? क्या आप अपनी 'फाइल' उस मशीन पर स्थानीय डिस्क पर हैं जिसका उपयोग आप कर रहे हैं, या इसे एनएफएस या इसी तरह का उपयोग करके एक्सेस किया गया है? नेटवर्क I/O अपराधी हो सकता है, और अन्य उपयोगकर्ता क्या कर रहे हैं इसके आधार पर मंदी यादृच्छिक रूप से दिखाई दे सकती है। – wildwilhelm

+0

@wildwilhelm फ़ाइल मशीन की स्थानीय डिस्क पर संग्रहीत नहीं है, इसलिए शायद यह एक नेटवर्क I/O समस्या है। मैं आगे बढ़ता हूं और यह देखने के लिए नेटवर्क अपलोड/डाउनलोड की निगरानी करता हूं कि कोई सहसंबंध है या नहीं! – Lewis

उत्तर

0

सीपीयू उपयोग में बूंद पाइथन या numpy से असंबंधित थे, लेकिन वास्तव में साझा डिस्क से पढ़ने का नतीजा था, और नेटवर्क I/O असली अपराधी था। ऐसे बड़े सरणी के लिए, स्मृति में पढ़ना एक बड़ी बाधा हो सकती है।

1

np.where वहां एक प्रति बना रहा है और इसे arr में वापस सौंप रहा है। तो, हम स्मृति पर वहाँ एक नकल कदम से बचकर, अनुकूलन कर सकता है जिससे की तरह -

vol_avg = (np.sum(arr) - (arr[arr >= 1.0] - 1.0).sum())/(num**3) 

हम boolean-indexing उपयोग कर रहे हैं तत्वों कि 1.0 से अधिक और कर रहे हैं का चयन करने के 1.0 से उनके ऑफसेट हो रही है और उन संक्षेप और से घटाकर कुल योग उम्मीद है कि इस तरह के अधिक से अधिक तत्वों की संख्या कम है और इस तरह अब ध्यान देने योग्य स्मृति आवश्यकता नहीं होगी। मुझे लगता है कि बड़े सरणी के साथ इस लटकती हुई समस्या एक स्मृति आधारित है।

+0

आपको लगता है कि मॉलोक अस्थायी रूप से ओएस में लटका रहा है? – Aaron

+0

@Aaron यकीन नहीं है कि स्मृति केवल एकमात्र अपराधी है, लेकिन उम्मीद है कि स्मृति समस्या है, इससे इस समस्या की स्मृति आवश्यकता को कम करने में मदद मिलनी चाहिए, खासकर जब से ओपी ने बड़े एरे के साथ यह किया है। – Divakar

+0

क्या आप वाकई कुछ बचाते हैं? मुझे लगता है कि 'arr> = 1.0', फिर' arr [arr> = 1.0] ', फिर' arr [arr> = 1.0] ', फिर' 'arr 'arr> = 1.0] - 1.0' प्रत्येक में नए सरणी, बूलियन के पहले, फिर एक उप-समूह शामिल होगा मूल सरणी, फिर मूल सरणी की एक उत्परिवर्तित प्रति। जब अभिव्यक्ति समाप्त होती है, तो वे सभी साफ़ हो जाएंगे, लेकिन फ़िल्टर अभिव्यक्ति मूल सरणी की लगभग एक चौथाई रैम पर कब्जा कर लेगी, और दो मध्यवर्ती फ़िल्टर पारित मूल्यों की संख्या के अनुपात में आनुपातिक डेटा पर कब्जा करेंगे। ओपी का कोड आवश्यक स्मृति (संक्षेप में) को दोगुना करता है, लेकिन इसमें लगातार लागत होती है। – ShadowRanger

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

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