2016-04-01 6 views
9

मुझे प्रदर्शन बाधा मिली है। मैं बड़े सरणी के स्तंभ-वार माध्य (250 पंक्तियों & 1.3 मिलियन कॉलम) की गणना कर रहा हूं, और मैं अपने आवेदन में दस लाख से अधिक बार ऐसा करता हूं। अजगर मेंउच्च प्रदर्शन सरणी का मतलब

मेरे परीक्षण का मामला:

import numpy as np 
big_array = np.random.random((250, 1300000)) 
%timeit mean = big_array.mean(axis = 0) # ~400 milliseconds 

Numpy मेरी मशीन पर लगभग 400 मिलीसेकेंड लेता है, एक सिंगल कोर पर चल रहा है। मैंने विभिन्न भाषाओं (साइथन, आर, जूलिया, मशाल) में कई अन्य मैट्रिक्स पुस्तकालयों की कोशिश की है, लेकिन लगभग 250 मिलीसेकंड लेकर, केवल जूलिया को नम्पी को हराया।

क्या कोई इस कार्य में प्रदर्शन में पर्याप्त सुधार के सबूत प्रदान कर सकता है? शायद यह एक कार्य GPU के लिए उपयुक्त है?

संपादित करें: मेरा आवेदन स्पष्ट रूप से स्मृति-बाधित है, और इसके प्रदर्शन को बार-बार की बजाय एक बार बड़ी सरणी के तत्वों तक पहुंचकर नाटकीय रूप से सुधार किया जाता है। (नीचे टिप्पणी देखें।)

+1

यह गणना शायद सीपीयू कार्य की तुलना में स्मृति पहुंच के बारे में अधिक है। मैं उम्मीद नहीं करता कि यहां किसी भी प्रणाली को सुस्त पर काफी सुधार होगा। मेरा अंतर्ज्ञान यह है कि एकाधिक कोर या जीपीयू का उपयोग अधिक उपयोग नहीं किया जाएगा। हालांकि float32 को कम करने में मदद मिल सकती है। – MRocklin

+0

टेस्ट केस बहुत आसान हो सकता है। मेरा सरणी प्रकार वास्तव में बूलियन होने जा रहा है, इसलिए हर तत्व को बेवकूफ के साथ बाइट के रूप में संग्रहीत किया जाता है। विरोधाभासी रूप से, उदाहरण के लिए फ्लोट्स की तुलना में बुलियन सरणी के लिए औसत या योग प्राप्त करने में अधिक समय लगता है। बिटकपैड सरणी पर ऑपरेशन करने का कोई विचार है, जो ~ 9 0% तक मेमोरी यातायात को कम करेगा? –

+0

मेरे विशेष एप्लिकेशन में, मैं उन सरणी का अर्थ लेता हूं जो 22,000-पंक्ति सरणी के 250-पंक्ति उप-समूह हैं। पूरे गणना के लिए मेमोरी कुल 24+ घंटे तक पहुंच जाती है। यदि मैं बड़े मैट्रिक्स पर काम करता हूं, हालांकि, केवल एक बार प्रत्येक तत्व को स्पर्श करता हूं, तो स्मृति कुल 10 सेकंड से कम तक पहुंच जाता है। मुझे कोशिश करनी होगी! बाधा को इंगित करने के लिए धन्यवाद @MRocklin। –

उत्तर

9

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

In [1]: import numpy as np 

In [2]: big_array = np.random.random((250, 1300000)) 

In [4]: big_array_f = np.asfortranarray(big_array) 

In [5]: %timeit mean = big_array.mean(axis = 0) 
1 loop, best of 3: 319 ms per loop 

In [6]: %timeit mean = big_array_f.mean(axis = 0) 
1 loop, best of 3: 205 ms per loop 

या आप केवल आपके आयाम बदलने और अन्य अक्ष से अधिक मतलब ले जा सकते हैं:

In [10]: big_array = np.random.random((1300000, 250)) 

In [11]: %timeit mean = big_array.mean(axis = 1) 
1 loop, best of 3: 205 ms per loop 
+0

मेरे कंप्यूटर पर, समय उलट दिया गया है: में [56]:% timeit big_array.mean (0) -> 705 एमएस प्रति लूप; में [57]:% timeit big_arrayf.mean (0) -> 1201 एमएस प्रति लूप; क्या आपको कोई विचार है? –

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