2012-06-28 16 views
6

, यह min के साथ एक reduction खंड करना संभव है:सरणी में कम से कम तत्व ढूँढना, और इसके सूचकांक OpenMP 3.1 के साथ

double m; 
#pragma omp parallel for reduction(min:m) 
for (int i=0;i< n; i++){ 
    if (a[i]*2 < m) { 
    m = a[i] * 2; 
} 
return m; 

मान लीजिए मैं भी सूचकांक कम से कम तत्व की की जरूरत है; इसके लिए reduction खंड का उपयोग करने का कोई तरीका है? मेरा मानना ​​है कि विकल्प nowait और critical का उपयोग करके मैन्युअल रूप से कमी को लिख रहा है।

उत्तर

5

मान लीजिए मुझे न्यूनतम तत्व की अनुक्रमणिका भी चाहिए; क्या इसके लिए कमी खंड का उपयोग करने का कोई तरीका है?

दुर्भाग्य से, नहीं। ओपनएमपी में संभावित कमी की सूची बहुत छोटी है। विशेष रूप से, min और max केवल "उच्च-स्तरीय" फ़ंक्शन हैं और वे अनुकूलन योग्य नहीं हैं। बिलकुल।

मुझे यह मानना ​​है कि मुझे ओपनएमपी के कटौती के दृष्टिकोण को पसंद नहीं है, ठीक है क्योंकि यह मामूली में एक्स्टेंसिबल नहीं है, यह केवल डिज़ाइन किया गया है विशेष मामलों पर काम करने के लिए। अनुमोदित, वे दिलचस्प विशेष मामले हैं लेकिन यह अभी भी मूल रूप से एक बुरा दृष्टिकोण है।

ऐसे परिचालनों के लिए, आपको थ्रेड-स्थानीय परिणामों को थ्रेड-स्थानीय चर में जमा करके और अंत में संयोजन करके स्वयं को कम करने की आवश्यकता है।

ऐसा करने का सबसे आसान तरीका (और वास्तव में ओपनएमपी कार्यान्वयन कैसे करता है इसके करीब है) प्रत्येक थ्रेड के लिए तत्वों के साथ एक सरणी है, और तत्व को एक्सेस करने के लिए omp_get_thread_num() का उपयोग करना है। ध्यान दें कि अगर सरणी में तत्व कैश लाइन साझा करते हैं तो यह झूठी साझाकरण के कारण प्रदर्शन में गिरावट का कारण बन जाएगा। इसे कम करने के लिए, सरणी को पैड करें:

struct min_element_t { 
    double min_val; 
    size_t min_index; 
}; 

size_t const CACHE_LINE_SIZE = 1024; // for example. 
std::vector<min_element_t> mins(threadnum * CACHE_LINE_SIZE); 

#pragma omp parallel for 
for (int i = 0; i < n; ++i) { 
    size_t const index = omp_get_thread_num() * CACHE_LINE_SIZE; 
    // operate on mins[index] … 
} 
+0

मुझे लगता है कि आपका मतलब 'omp_get_num_threads' था? – user1071136

+0

@ user1071136 नहीं, मेरा मतलब है 'omp_get_thread_num'। हम * सूचकांक * चाहते हैं, कुल संख्या नहीं। और 'थ्रेडनम' के लिए, यह प्लेसहोल्डर है। आप यहां 'omp_get_num_threads' का उपयोग नहीं कर सकते हैं क्योंकि आप समांतर क्षेत्र के अंदर नहीं हैं। इसके बजाए, आपको वास्तव में बाद के समानांतर खंड में धागे की संख्या के रूप में 'numthread' पास करना चाहिए। झूठी साझाकरण का उल्लेख करने के लिए –

+0

+1। फिर भी, ओपनएमपी कमी खंडों को दक्षता और आसान कार्यान्वयन के लिए डिजाइन किया गया था, विस्तार के लिए नहीं। –

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