2014-10-31 4 views
8

मैं एक मेमोरी एक्सेस प्रयोग चला रहा हूं जिसमें प्रत्येक पंक्ति के साथ 2 डी मैट्रिक्स का उपयोग स्मृति पृष्ठ के आकार के रूप में किया जाता था। प्रयोग में पंक्ति/कॉलम प्रमुख का उपयोग करके प्रत्येक तत्व को पढ़ने और फिर पंक्ति/कॉलम प्रमुख का उपयोग करके प्रत्येक तत्व को लिखना शामिल है। प्रोग्रामिंग आवश्यकताओं को कम करने के लिए उपयोग किए जा रहे मैट्रिक्स को वैश्विक दायरे के साथ घोषित किया गया था।अन्य मूल्यों को पढ़ने से स्मृति से "शून्य" को तेज़ी से पढ़ रहा है?

इस प्रश्न का मुद्दा यह है कि परीक्षण मैट्रिक्स को स्थैतिक रूप से घोषित किया जा रहा है, मानकों को संकलक द्वारा शून्य में प्रारंभ किया गया है और मुझे मिले परिणाम काफी रोचक थे। जब मैंने पहले ऑपरेशन पढ़े, यानी

rowMajor_read(); 
colMajor_read(); 
rowMajor_write(); 
colMajor_write(); 

तब मेरा colMajor_read ऑपरेशन बहुत जल्दी समाप्त हो गया। enter image description here

हालांकि, हम पूछना चाहते हैं तो मैं पढ़ने से पहले लिखने के संचालन कार्य करें:

rowMajor_write(); 
colMajor_write(); 
rowMajor_read(); 
colMajor_read(); 

enter image description here

और स्तंभ-प्रमुख पढ़ने आपरेशन परिमाण के लगभग एक आदेश की वृद्धि हुई है।

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

मैं अनुकूलन के संबंध में कोई विशेष कंपाइलर आदेश नहीं पारित करता हूं, लेकिन मैंने इस तरह से अपने कार्यों की घोषणा की।

inline void colMajor_read(){ 
    register int row, col; 
    register volatile char temp __attribute__((unused)); 
    for(col = 0; col < COL_COUNT; col++) 
     for(row = 0; row < ROW_COUNT; row++) 
      temp = testArray[row][col]; 
} 

क्योंकि मैं मुद्दों जहां संकलक पूरी तरह से के बाद से यह प्रयोग किया जा रहा कभी नहीं किया गया था इसके बाद के संस्करण समारोह से temp चर हटाया में चल रहा था। मुझे लगता है कि volatile और __attribute__((unused)) दोनों अनावश्यक हैं, लेकिन मैंने इसे फिर भी शामिल किया है। मैं इस धारणा के तहत था कि एक अस्थिर चर पर कोई अनुकूलन लागू नहीं किया गया था।

कोई विचार?


मैंने जेनरेट की गई असेंबली को देखा और परिणाम colMajor_read फ़ंक्शन के लिए समान हैं। (असेंबली) गैर-इनलाइन संस्करण: http://pastebin.com/C8062fYB

+5

मेरा अनुमान सिस्टम कैश और भविष्यवाणी के साथ है। – Nit

+1

मैं @Nit के साथ सहमत हूं। कैश इलाके सबसे अधिक संभावना भिन्नता का स्रोत है। कैश आसानी से 10x एक्सेस समय सुधार दे सकते हैं। यदि आप संकलन को दूर करने वाले संकलक को गंभीरता से संदेह करते हैं (कार्यों में असंभव है, लेकिन सख्ती से असंभव नहीं है), तो जांचने के लिए अपने सी कार्यों के एक असेंबलर आउटपुट प्राप्त करें। –

+2

लोगों पर रुको। मुझे यह सब जटिल नहीं लगता है। क्योंकि विधियों को रेखांकित किया गया है, इसका मतलब है कि ये सभी कार्य एक ही संकलन इकाई के भीतर हैं, इसलिए संकलक शानदार चीजें कर सकते हैं। मुख्य रूप से, यह बता सकता है कि आपने पढ़ने और लिखने के बाद चर बदल दिया है, इसलिए यह आसानी से कोड को 'temp = 0' के रूप में दोबारा परिभाषित कर सकता है, जो तुलनात्मक रूप से पागल हो जाएगा। क्या आप असेंबली पोस्ट कर सकते हैं? – IdeaHat

उत्तर

7

मैट्रिक्स को मान लिखने से पहले और बाद में अपनी प्रक्रिया के स्मृति उपयोग की जांच करें। यदि यह लिनक्स पर .bss अनुभाग में संग्रहीत है, उदाहरण के लिए, शून्य पृष्ठों को कॉपी-ऑन-राइट सेमेन्टिक्स के साथ एक एकल-पढ़ने वाले पृष्ठ पर मैप किया जाएगा। तो, भले ही आप पते के समूह के माध्यम से पढ़ रहे हों, आप भौतिक स्मृति के एक ही पृष्ठ को और अधिक पढ़ सकते हैं।

यह पृष्ठ http://madalanarayana.wordpress.com/2014/01/22/bss-segment/ एक अच्छा स्पष्टीकरण है।

यदि ऐसा है, तो बाद में मैट्रिक्स को शून्य करें और अपने पढ़ने के परीक्षण को दोबारा शुरू करें और यह अब इतना तेज़ नहीं होना चाहिए।

+0

+1 जब मैंने देखा कि मैं 16 घंटे देर से था, तो इसे पोस्ट करने वाला था। – Mehrdad

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