एक साधारण जवाब:
OpenMP केवल कई कोर के लिए एक से अधिक थ्रेड का फायदा उठाने के लिए इस्तेमाल किया। यह नया simd
विस्तार आपको आधुनिक CPUs जैसे कि इंटेल के AVX/SSE और ARM के NEON पर सिम निर्देश का स्पष्ट रूप से उपयोग करने की अनुमति देता है।
(ध्यान दें कि डिज़ाइन द्वारा एक सिम निर्देश को एक थ्रेड और एकल कोर में निष्पादित किया जाता है। हालांकि, सिमड का अर्थ जीपीजीपीयू के लिए काफी विस्तारित किया जा सकता है। लेकिन, लेकिन मुझे नहीं लगता कि आपको GPGPU पर विचार करने की आवश्यकता है ओपनएमपी 4.0 के लिए।)
तो, एक बार जब आप सिमड निर्देशों को जानते हैं, तो आप इस नए निर्माण का उपयोग कर सकते हैं।
एक आधुनिक सीपीयू में, मोटे तौर पर वहाँ समानांतरवाद के तीन प्रकार हैं: (1) शिक्षा स्तर के समानांतरवाद (आईएलपी), (2) धागा स्तरीय समानांतरवाद (TLP), और (3) SIMD निर्देश (हम कह सकता है कि यह वेक्टर-स्तर या तो है)।
आईएलपी स्वचालित रूप से आपके आउट-ऑफ-ऑर्डर CPUs या कंपाइलर्स द्वारा किया जाता है। आप ओपनएमपी के parallel for
और अन्य थ्रेडिंग लाइब्रेरी का उपयोग कर टीएलपी का फायदा उठा सकते हैं। तो, सिम के बारे में क्या? इंट्रिनिक्स उन्हें उपयोग करने का एक तरीका था (साथ ही साथ कंपाइलर्स 'स्वचालित वेक्टरेशन)। ओपनएमपी का simd
सिमड का उपयोग करने का एक नया तरीका है।
एक बहुत ही सरल उदाहरण लें:
for (int i = 0; i < N; ++i)
A[i] = B[i] + C[i];
ऊपर कोड दो एन आयामी वैक्टर की राशि की गणना करता है।जैसा कि आप आसानी से देख सकते हैं, A[]
सरणी पर (loop-carried) data dependency नहीं है। यह लूप embarrassingly parallel है।
इस लूप को समानांतर करने के कई तरीके हो सकते हैं। उदाहरण के लिए, ओपनएमपी 4.0 तक, इसे केवल parallel for
निर्माण का उपयोग करके समांतर किया जा सकता है। प्रत्येक थ्रेड एकाधिक कोर पर N/#thread
पुनरावृत्तियों का प्रदर्शन करेगा।
हालांकि, आपको लगता है कि इस तरह के सरल जोड़ के लिए कई धागे का उपयोग करना एक ओवरकिल होगा। यही कारण है कि वेक्टरेशन है, जिसे ज्यादातर सिम निर्देशों द्वारा कार्यान्वित किया जाता है।
एक SIMD का उपयोग करते हुए इस तरह होगा:
for (int i = 0; i < N/8; ++i)
VECTOR_ADD(A + i, B + i, C + i);
इस कोड को मानता है कि (1) SIMD निर्देश (VECTOR_ADD
) है 256-बिट या 8-तरफा (8 * 32 बिट); और (2) N
8.
एक 8-तरफा सिमड निर्देश का अर्थ है कि एक वेक्टर में 8 आइटम एक मशीन निर्देश में निष्पादित किए जा सकते हैं। ध्यान दें कि इंटेल का नवीनतम एवीएक्स ऐसे 8-मार्ग (32-बिट * 8 = 256 बिट्स) वेक्टर निर्देश प्रदान करता है।
सिम में, आप अभी भी एक कोर का उपयोग करते हैं (फिर से, यह केवल पारंपरिक सीपीयू के लिए है, जीपीयू नहीं)। लेकिन, आप हार्डवेयर में एक छिपी समानांतरता का उपयोग कर सकते हैं। आधुनिक सीपीयू सिमड निर्देशों के लिए हार्डवेयर संसाधनों को समर्पित करते हैं, जहां प्रत्येक सिम लेन समानांतर में निष्पादित किया जा सकता है।
आप एक ही समय में थ्रेड-स्तर समांतरता का उपयोग कर सकते हैं। उपर्युक्त उदाहरण parallel for
द्वारा आगे समानांतर किया जा सकता है।
(हालांकि, मुझे संदेह है कि कितने लूप वास्तव में सिमडिज्ड लूप में परिवर्तित हो सकते हैं। ओपनएमपी 4.0 विनिर्देश इस पर थोड़ा अस्पष्ट लगता है। इसलिए, असली प्रदर्शन और व्यावहारिक प्रतिबंध वास्तविक कंपाइलर्स के कार्यान्वयन पर निर्भर होंगे।)
संक्षेप में, simd
निर्माण आप SIMD निर्देश का उपयोग करने की अनुमति देता है, बारी में, अधिक समानांतरवाद धागा स्तरीय समानांतरवाद के साथ इस्तेमाल किया जा सकता। हालांकि, मुझे लगता है कि वास्तविक कार्यान्वयन महत्वपूर्ण होगा।
ओपनएमएम यूंटिल संस्करण 3.0 को सिमड किया गया था, फिर उन्होंने उस अवधारणा को छोड़ दिया। मुझे लगता है कि नई प्रगति पुराने कोड के साथ पिछड़ा संगतता के लिए है जो सिम के कुछ पहलुओं पर निर्भर थी। ओपनएमपी डॉक्स के बारे में कुछ कहना नहीं चाहिए? –
यह 'समांतर सिमड' नहीं है; आप 'समांतर' _or_ 'simd' का उपयोग करते हैं, जो भेद पर संकेत देता है। निचे देखो। –
@ जेडी: यह निश्चित रूप से एक टाइपो था। फिक्स्ड, धन्यवाद –