2012-07-20 13 views
16

मेरे पास स्मृति की ब्लॉक है जो काफी बड़ी हो सकती है (एल 2 कैश से बड़ी), और कभी-कभी मुझे उन्हें सभी शून्य पर सेट करना होगा। स्मृति एक सीरियल कोड में अच्छा है, लेकिन समांतर कोड के बारे में क्या? क्या किसी का अनुभव है यदि समवर्ती धागे से मेमसेट को कॉल करना वास्तव में बड़े सरणी के लिए चीजों को गति देता है? या यहां तक ​​कि लूप के लिए समान openmp समानांतर का उपयोग भी?ओपनएमपी समांतर कोड में, समानांतर में मेमसेट चलाने के लिए कोई लाभ होगा?

+1

असंभव। कैश से बाहर डेटा पर 'मेमसेट' की संभावना स्मृति बैंडविड्थ द्वारा बाधित की जाएगी। – Mysticial

+1

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

+1

फिर भी, उद्योग मानक [स्ट्रीम बेंचमार्क] (http://www.cs.virginia.edu/stream/) है। [ओपनएमपी संस्करण] (http://www.cs.virginia.edu/stream/FTP/Code/Versions/stream_omp.c) को पकड़ें, अपने आप को देखने के लिए विभिन्न संख्याओं के साथ संकलित करें और चलाएं। ध्यान दें कि 'memset() 'अधिकांश' libc' कार्यान्वयन में सिम-सक्षम है और पहले ही मेमोरी बैंडविड्थ को अपने चरम पर दबा रहा है। –

उत्तर

20

एचपीसी में लोग आमतौर पर कहते हैं कि एक धागा आमतौर पर एक मेमोरी लिंक को संतृप्त करने के लिए पर्याप्त नहीं होता है, जो आमतौर पर नेटवर्क लिंक के लिए भी सच होता है। Here एक त्वरित और गंदा ओपनएमपी सक्षम मेमसेटर है जो मैंने आपके लिए लिखा है जो शून्य के साथ 2 जीबी 2 जीबी के साथ भरता है।

जीसीसी 4.7, कोड -O3 -mtune=native -fopenmp साथ संकलित: और यहाँ (सूचना कई रन से अधिकतम मान) जीसीसी 4.7 का उपयोग कर परिणाम अलग आर्किटेक्चर पर धागे के विभिन्न संख्या के साथ कर रहे हैं

क्वैड सॉकेट इंटेल जिऑन X7350 - अलग स्मृति नियंत्रक और मोर्चा साइड बस

एकल सॉकेट के साथ पूर्व Nehalem क्वाड-कोर सीपीयू

threads 1st touch  rewrite 
1   1452.223 MB/s 3279.745 MB/s 
2   1541.130 MB/s 3227.216 MB/s 
3   1502.889 MB/s 3215.992 MB/s 
4   1468.931 MB/s 3201.481 MB/s 

(1 स्पर्श धीमी है के रूप में धागा टीम खरोंच से बनाया जा रहा है और ऑपरेटिंग सिस्टम वर्चुअल ऐड्रेस स्पेस malloc(3) द्वारा आरक्षित में शारीरिक पृष्ठों मैपिंग कर रहा है)

एक थ्रेड पहले से ही एक CPU < की स्मृति बैंडविड्थ संतृप्त -> एनबी लिंक। > स्मृति लिंक - (नायब = नॉर्थ ब्रिज) सॉकेट प्रति

1 धागा

threads 1st touch  rewrite 
1   1455.603 MB/s 3273.959 MB/s 
2   2824.883 MB/s 5346.416 MB/s 
3   3979.515 MB/s 5301.140 MB/s 
4   4128.784 MB/s 5296.082 MB/s 

दो धागे नायब < से भरा स्मृति बैंडविड्थ को परिपूर्ण करने के लिए आवश्यक हैं।

अक्तूबर-सॉकेट इंटेल जिऑन X7550 - 8-तरीका NUMA अक्तूबर-कोर सीपीयू (CMT विकलांग)

एकल सॉकेट

threads 1st touch  rewrite 
1   1469.897 MB/s 3435.087 MB/s 
2   2801.953 MB/s 6527.076 MB/s 
3   3805.691 MB/s 9297.412 MB/s 
4   4647.067 MB/s 10816.266 MB/s 
5   5159.968 MB/s 11220.991 MB/s 
6   5330.690 MB/s 11227.760 MB/s 

कम से कम 5 धागे क्रम में परिपूर्ण करने के लिए आवश्यक हैं के साथ प्रणाली एक मेमोरी लिंक की बैंडविड्थ।

1 सॉकेट

threads 1st touch  rewrite 
1   1460.012 MB/s 3436.950 MB/s 
2   2928.678 MB/s 6866.857 MB/s 
3   4408.359 MB/s 10301.129 MB/s 
4   5859.548 MB/s 13712.755 MB/s 
5   7276.209 MB/s 16940.793 MB/s 
6   8760.900 MB/s 20252.937 MB/s 

बैंडविड्थ प्रति धागा धागे की संख्या के साथ लगभग रैखिक पैमाने। सिंगल-सॉकेट अवलोकनों के आधार पर कोई यह कह सकता है कि आठ मेमोरी लिंक को संतृप्त करने के लिए प्रति सॉकेट 5 धागे के रूप में वितरित कम से कम 40 धागे आवश्यक होंगे।

NUMA सिस्टम पर मूल समस्या पहली स्पर्श स्मृति नीति है - स्मृति को NUMA नोड पर आवंटित किया जाता है जहां थ्रेड पहले किसी विशिष्ट पृष्ठ निष्पादन के भीतर वर्चुअल एड्रेस को स्पर्श करता है।थ्रेड पिनिंग (विशिष्ट सीपीयू कोर के लिए बाध्यकारी) ऐसे सिस्टम पर आवश्यक है क्योंकि थ्रेड माइग्रेशन रिमोट एक्सेस की ओर जाता है, जो धीमा है। पिनीग के लिए समर्थित अधिकांश ओपनएमपी रनटाइम में उपलब्ध है। libgomp के साथ जीसीसी GOMP_CPU_AFFINITY पर्यावरण चर है, इंटेल के पास KMP_AFFINITY पर्यावरण परिवर्तक इत्यादि है। इसके अलावा, ओपनएमपी 4.0 ने स्थानों की विक्रेता-तटस्थ अवधारणा पेश की है।

संपादित करें: पूर्णता के लिए, यहाँ एक 1 GiB (हिंदुस्तान टाइम्स और QPI साथ डुअल कोर सैंडी ब्रिज सीपीयू) के साथ इंटेल कोर i5-2557M मैकबुक एयर पर सरणी के साथ कोड चलाने के परिणाम हैं। कंपाइलर जीसीसी 4.2.1 (ऐप्पल एलएलवीएम बिल्ड)

threads 1st touch  rewrite 
1   2257.699 MB/s 7659.678 MB/s 
2   3282.500 MB/s 8157.528 MB/s 
3   4109.371 MB/s 8157.335 MB/s 
4   4591.780 MB/s 8141.439 MB/s 

यह उच्च गति भी एक धागे के साथ क्यों? gdb के साथ एक छोटी सी खोज से पता चलता है कि memset(buf, 0, len) को ओएस एक्स कंपाइलर द्वारा bzero(buf, len) पर अनुवादित किया गया है और bzero$VARIANT$sse42 के नाम से एक एसएसई 4.2 सक्षम वेक्टरिज्ड संस्करण libc.dylib द्वारा प्रदान किया जाता है और रन-टाइम पर उपयोग किया जाता है। यह MOVDQA निर्देश को शून्य के 16 बाइट्स मेमोरी में एक बार में उपयोग करता है। यही कारण है कि एक धागे के साथ भी स्मृति बैंडविड्थ लगभग संतृप्त है। VMOVDQA का उपयोग कर एकल-थ्रेडेड AVX सक्षम संस्करण एक बार में 32 बाइट शून्य हो सकता है और संभवतः स्मृति लिंक को संतृप्त कर सकता है।

यहां महत्वपूर्ण संदेश यह है कि कभी-कभी वेक्टरिसेशन और मल्टीथ्रेडिंग ऑपरेशन तक गति लाने में ऑर्थोगोनल नहीं होती है।

+0

इन परिणामों के लिए धन्यवाद। आप "1 थ्रेड/सॉकेट" या "1 सॉकेट में सभी धागे" को कैसे नियंत्रित करते हैं? –

+1

'टास्कसेट' और/या' GOMP_CPU_AFFINITY' चर सेट करने के साथ। यदि आपके पास 'hwloc' स्थापित है तो यह निफ्टी 'hwloc-ls' उपकरण प्रदान करता है। बस इसे 'hwloc-ls - टास्कसेट' की तरह चलाएं और यह आपको 'टास्कसेट' के लिए आवश्यक बिटमैस्क दिखाएगा उदा। एक सॉकेट पर चलाएं। –

+0

यह एक अच्छा जवाब है। लेकिन क्या आप पहले बता सकते हैं कि पहले स्पर्श और फिर से लिखने के बीच इतना अंतर क्यों है? मैं पूरी तरह से समझ नहीं पा रहा हूं कि "पहला स्पर्श धीमा है क्योंकि थ्रेड टीम स्क्रैच से बनाई जा रही है और ऑपरेटिंग सिस्टम भौतिक पृष्ठों को मैलोक (3)" –

1

ठीक है, वहाँ हमेशा L3 कैश है ...

हालांकि, यह बहुत संभव है कि यह मुख्य स्मृति बैंडविड्थ को पहले से ही लागू होंगे है; अधिक समांतरता जोड़ने से चीजों को बेहतर बनाने की संभावना नहीं है।

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