2012-02-15 11 views
5

मेरे सीपीयू 2 कोर और 4 धागे के साथ एक Core i3 330M है। जब मैं अपने टर्मिनल में बिल्ली /proc/cpuinfo कमांड निष्पादित करता हूं, तो ऐसा लगता है कि मेरे पास 4 सीपीयूएस है। जब मैं ओपनएमपी फ़ंक्शन get_omp_num_procs() का उपयोग करता हूं तो मुझे भी 4.OpenMP और कोर/धागे

अब मेरे पास मानक सी ++ वेक्टर क्लास है, मेरा मतलब है कि एक निश्चित आकार की डबल सरणी कक्षा है जो अभिव्यक्ति टेम्पलेट्स का उपयोग नहीं करती है। मैंने सावधानीपूर्वक मेरी कक्षा के सभी तरीकों को समानांतर किया है और मुझे "अपेक्षित" गति मिलती है।

सवाल यह है: मैं इस तरह के एक सरल मामले में की उम्मीद speedup अनुमान लगा सकते हैं? उदाहरण के लिए, यदि मैं समानांतर लूप के बिना दो वैक्टर जोड़ता हूं तो मुझे कुछ समय मिलता है (शेल टाइम कमांड का उपयोग करके)। अब अगर मैं ओपनएमपी का उपयोग करता हूं, तो क्या मुझे कोर/थ्रेड्स की संख्या के अनुसार 2 या 4 से विभाजित समय मिलना चाहिए? मैं जोर देता हूं कि मैं केवल इस विशेष साधारण समस्या के लिए पूछ रहा हूं, जहां डेटा में कोई परस्पर निर्भरता नहीं है और सबकुछ रैखिक (वेक्टर अतिरिक्त) है।

Vector Vector::operator+(const Vector& rhs) const 
{ 
    assert(m_size == rhs.m_size); 
    Vector result(m_size); 
    #pragma omp parallel for schedule(static) 
    for (unsigned int i = 0; i < m_size; i++) 
      result.m_data[i] = m_data[i]+rhs.m_data[i]; 

    return result; 
} 

मैं पहले से ही इस पोस्ट को पढ़ लिया है: OpenMP thread mapping to physical cores

यहाँ कुछ कोड है।

मुझे आशा है कि किसी ने मुझसे बारे में कैसे OpenMP काम इस सरल मामले में करवाने अधिक बता देंगे। मुझे कहना चाहिए कि मैं समांतर कंप्यूटिंग में एक नौसिखिया हूं।

धन्यवाद!

उत्तर

3

संपादित करें: अब जब कि कुछ कोड जोड़ दिया गया है।

उस विशेष उदाहरण में, बहुत कम गणना और स्मृति की बहुत सारी पहुंच है। तो प्रदर्शन पर निर्भर करेगा:

  • वेक्टर का आकार।
  • आप इसे कैसे समय दे रहे हैं। (क्या आपके पास समय उद्देश्यों के लिए बाहरी-लूप है)
  • चाहे डेटा पहले से ही कैश में है।

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

मैं हार्ड नंबर देने से इनकार करता हूं क्योंकि आम तौर पर, "अनुमान लगाया" प्रदर्शन, विशेष रूप से बहु-थ्रेडेड अनुप्रयोगों में एक खोया कारण होता है जब तक कि आपके पास पहले से ही प्रोग्राम और सिस्टम और दोनों सिस्टम के अंतरंग ज्ञान का ज्ञान नहीं होता है।

एक सरल उदाहरण मेरा उत्तर यहाँ से लिया बस के रूप में: How to get 100% CPU usage from a C program

@ 3 एक कोर i7 920 पर।5 GHz (4 कोर, 8 धागे):

अगर मैं 4 धागे साथ चलाने के लिए, परिणाम है:

This machine calculated all 78498 prime numbers under 1000000 in 39.3498 seconds 

अगर मैं 4 धागे और स्पष्ट रूप से चलाने के (कार्य प्रबंधक का उपयोग) 4 अलग शारीरिक कोर पर धागे पिन, परिणाम है:

This machine calculated all 78498 prime numbers under 1000000 in 30.4429 seconds 

तो यह दिखाता है कि यह एक बहुत ही सरल और शर्मनाक समानांतर अनुप्रयोग के लिए कितना अप्रत्याशित है। भारी मेमोरी उपयोग और सिंक्रनाइज़ेशन से जुड़े अनुप्रयोगों में बहुत कुछ मिलता है ...

1

रहस्यमय उत्तर में जोड़ने के लिए। आपकी समस्या पूरी तरह से मेमोरी बैंडविड्थ है। STREAM benchmark पर एक नज़र डालें। इसे अपने कंप्यूटर पर एकल और बहु-थ्रेडेड मामलों में चलाएं, और ट्रायड परिणामों को देखें - यह आपका मामला है (ठीक है, लगभग, क्योंकि आपका आउटपुट वेक्टर एक ही समय में आपके इनपुट वैक्टर में से एक है)। गणना करें कि आप कितने डेटा को स्थानांतरित करते हैं और आपको पता चलेगा कि वास्तव में किस प्रदर्शन की अपेक्षा की जा सकती है।

क्या इस समस्या के लिए बहु-थ्रेडिंग काम करता है? हाँ। यह दुर्लभ है कि एक एकल सीपीयू कोर सिस्टम की पूरी मेमोरी बैंडविड्थ को संतृप्त कर सकता है। आधुनिक कंप्यूटर उपलब्ध स्मृति बैंडविड्थ को उपलब्ध कोर की संख्या के साथ संतुलित करते हैं। मेरे अनुभव से आपको मेमोरी बैंडविड्थ को एक साधारण मेमकोपी ऑपरेशन के साथ संतृप्त करने के लिए लगभग आधा कोर की आवश्यकता होगी। यदि आप रास्ते पर कुछ गणना करते हैं तो इसमें कुछ और लग सकता है।

ध्यान दें कि NUMA सिस्टम पर आपको थ्रेड को सीपीयू कोर में बांधना होगा और इष्टतम परिणाम प्राप्त करने के लिए स्थानीय स्मृति आवंटन का उपयोग करना होगा। ऐसा इसलिए है क्योंकि इस तरह के सिस्टम पर प्रत्येक सीपीयू की अपनी स्थानीय मेमोरी होती है, जिस पर पहुंच सबसे तेज़ है। आप अभी भी पूरी तरह से एसएमपी की तरह पूरे सिस्टम मेमोरी तक पहुंच सकते हैं, लेकिन यह संचार लागत में आता है - सीपीयू को स्पष्ट रूप से डेटा का आदान-प्रदान करना होता है। सीपीयू को बाध्यकारी थ्रेड और स्थानीय आवंटन का उपयोग करना बेहद महत्वपूर्ण है। ऐसा करने में विफलता स्केलेबिलिटी को मार देती है। यदि आप लिनक्स पर ऐसा करना चाहते हैं तो libnuma की जांच करें।