C++
OpenMP के साथ सम्मिलितता
खोज…
परिचय
यह विषय OpenMP का उपयोग करके C ++ में संगामिति की मूल बातें शामिल करता है। OpenMP को OpenMP टैग में अधिक विवरण में प्रलेखित किया गया है।
समानांतरवाद या संगामिति का अर्थ है एक ही समय में कोड का निष्पादन।
टिप्पणियों
ओपनएमपी को किसी विशेष हेडर या लाइब्रेरी की आवश्यकता नहीं है क्योंकि यह एक अंतर्निहित कंपाइलर सुविधा है। हालाँकि, यदि आप omp_get_thread_num()
जैसे किसी भी OpenMP API फ़ंक्शन का उपयोग करते हैं, तो आपको omp.h
और इसकी लाइब्रेरी को शामिल करना होगा।
जब संकलन के दौरान OpenMP विकल्प सक्षम नहीं किया जाता है तो OpenMP pragma
विवरणों को अनदेखा कर दिया जाता है। आप अपने संकलक के मैनुअल में संकलक विकल्प को संदर्भित करना चाह सकते हैं।
- GCC
-fopenmp
का उपयोग करता है -
-fopenmp
का उपयोग करता है - MSVC का उपयोग करता है
/openmp
ओपनएमपी: समानांतर अनुभाग
यह उदाहरण समानांतर में कोड के वर्गों को निष्पादित करने की मूल बातें दिखाता है।
चूंकि ओपनएमपी एक अंतर्निहित कंपाइलर सुविधा है, यह किसी भी लाइब्रेरी को शामिल किए बिना किसी भी समर्थित कंपाइलर पर काम करता है। आप omp.h
को शामिल करना चाह सकते हैं यदि आप किसी भी ओपनपीएम एपीआई सुविधाओं का उपयोग करना चाहते हैं।
नमूना कोड
std::cout << "begin ";
// This pragma statement hints the compiler that the
// contents within the { } are to be executed in as
// parallel sections using openMP, the compiler will
// generate this chunk of code for parallel execution
#pragma omp parallel sections
{
// This pragma statement hints the compiler that
// this is a section that can be executed in parallel
// with other section, a single section will be executed
// by a single thread.
// Note that it is "section" as opposed to "sections" above
#pragma omp section
{
std::cout << "hello " << std::endl;
/** Do something **/
}
#pragma omp section
{
std::cout << "world " << std::endl;
/** Do something **/
}
}
// This line will not be executed until all the
// sections defined above terminates
std::cout << "end" << std::endl;
आउटपुट
यह उदाहरण 2 संभावित आउटपुट का उत्पादन करता है और ऑपरेटिंग सिस्टम और हार्डवेयर पर निर्भर है। आउटपुट एक दौड़ हालत समस्या को भी दिखाता है जो इस तरह के कार्यान्वयन से होता है।
OUTPUT A | OUTPUT बी |
---|---|
हैलो दुनिया का अंत शुरू | दुनिया हैलो अंत शुरू करते हैं |
ओपनएमपी: समानांतर अनुभाग
यह उदाहरण दिखाता है कि समानांतर में कोड के विखंडू को कैसे निष्पादित किया जाए
std::cout << "begin ";
// Start of parallel sections
#pragma omp parallel sections
{
// Execute these sections in parallel
#pragma omp section
{
... do something ...
std::cout << "hello ";
}
#pragma omp section
{
... do something ...
std::cout << "world ";
}
#pragma omp section
{
... do something ...
std::cout << "forever ";
}
}
// end of parallel sections
std::cout << "end";
उत्पादन
- हैलो दुनिया हमेशा के लिए शुरू करो
- शुरुआत विश्व हैलो हमेशा के लिए खत्म
- हैलो शुरू करो हमेशा के लिए दुनिया का अंत
- हमेशा के लिए हैलो दुनिया का अंत शुरू करो
जैसा कि निष्पादन आदेश की गारंटी नहीं है, आप उपरोक्त आउटपुट में से किसी का भी निरीक्षण कर सकते हैं।
ओपनएमपी: लूप के लिए समानांतर
यह उदाहरण दिखाता है कि कैसे एक लूप को समान भागों में विभाजित करें और उन्हें समानांतर में निष्पादित करें।
// Splits element vector into element.size() / Thread Qty
// and allocate that range for each thread.
#pragma omp parallel for
for (size_t i = 0; i < element.size(); ++i)
element[i] = ...
// Example Allocation (100 element per thread)
// Thread 1 : 0 ~ 99
// Thread 2 : 100 ~ 199
// Thread 2 : 200 ~ 299
// ...
// Continue process
// Only when all threads completed their allocated
// loop job
...
* लूप्स के लिए समानांतर में उपयोग किए गए वेक्टर के आकार को संशोधित न करने के लिए कृपया अतिरिक्त ध्यान रखें क्योंकि आवंटित सीमाएं स्वचालित रूप से अपडेट नहीं होती हैं ।
ओपनएमपी: समानांतर सभा / कटौती
यह उदाहरण std::vector
और OpenMP का उपयोग करके कमी या इकट्ठा करने के लिए एक अवधारणा को दिखाता है।
माना जाता है कि हमारे पास एक ऐसा परिदृश्य है जहाँ हम सामानों का एक समूह बनाने में मदद करने के लिए कई धागे चाहते हैं, यहाँ सादगी के लिए int
का उपयोग किया जाता है और इसे अन्य डेटा प्रकारों से बदला जा सकता है।
यह विशेष रूप से तब उपयोगी होता है जब आपको सेजमेंट दोष या मेमोरी एक्सेस उल्लंघन से बचने के लिए दास से परिणाम मर्ज करने की आवश्यकता होती है और लाइब्रेरी या कस्टम सिंक कंटेनर लाइब्रेरी का उपयोग करने की इच्छा नहीं होती है।
// The Master vector
// We want a vector of results gathered from slave threads
std::vector<int> Master;
// Hint the compiler to parallelize this { } of code
// with all available threads (usually the same as logical processor qty)
#pragma omp parallel
{
// In this area, you can write any code you want for each
// slave thread, in this case a vector to hold each of their results
// We don't have to worry about how many threads were spawn or if we need
// to repeat this declaration or not.
std::vector<int> Slave;
// Tell the compiler to use all threads allocated for this parallel region
// to perform this loop in parts. Actual load appx = 1000000 / Thread Qty
// The nowait keyword tells the compiler that the slave threads don't
// have to wait for all other slaves to finish this for loop job
#pragma omp for nowait
for (size_t i = 0; i < 1000000; ++i
{
/* Do something */
....
Slave.push_back(...);
}
// Slaves that finished their part of the job
// will perform this thread by thread one at a time
// critical section ensures that only 0 or 1 thread performs
// the { } at any time
#pragma omp critical
{
// Merge slave into master
// use move iterators instead, avoid copy unless
// you want to use it for something else after this section
Master.insert(Master.end(),
std::make_move_iterator(Slave.begin()),
std::make_move_iterator(Slave.end()));
}
}
// Have fun with Master vector
...