OpenMP के स्वर्ण नियम यह है कि सभी चर (कुछ बहिष्कारों के साथ), जिन्हें बाहरी क्षेत्र में परिभाषित किया गया है, समानांतर क्षेत्र में डिफ़ॉल्ट रूप से साझा किए जाते हैं। चूंकि 2008 से पहले फोरट्रान में कोई स्थानीय क्षेत्र नहीं है (यानी पिछले संस्करणों में BLOCK ... END BLOCK
नहीं है), सभी चर (threadprivate
वाले को छोड़कर) साझा किए जाते हैं, जो मेरे लिए बहुत स्वाभाविक है (इयान बुश के विपरीत, मैं उपयोग करने का बड़ा प्रशंसक नहीं हूं default(none)
और फिर विभिन्न जटिल वैज्ञानिक कोडों में सभी 100+ स्थानीय चरों की दृश्यता को फिर से शुरू करना)। , साझा क्योंकि यह सब धागे में एक ही होना चाहिए और वे केवल अपने मूल्य पढ़ा -
A
से अधिक कमी के साथ जगह में, प्रत्येक थ्रेड A
की अपनी निजी कॉपी प्राप्त होगा और यह एक स्मृति हॉग हो सकता है, हालांकि मुझे शक है तो आप इस प्रत्यक्ष हे (एन) अनुकरण कोड का प्रयोग करेंगे प्रणालियों की गणना करने के कणों की बहुत बड़ी संख्या के साथ। कमी कार्यान्वयन से जुड़े एक निश्चित ओवरहेड भी है। इस मामले में आपको REDUCTION(+:...)
खंड की सूची में A
जोड़ने की आवश्यकता है।
सिंक्रनाइज़िंग संरचनाओं के साथ आपके पास दो विकल्प हैं। आप या तो ATOMIC
निर्माण या CRITICAL
निर्माण इस्तेमाल कर सकते हैं। ATOMIC
केवल अदिश संदर्भों के लिए लागू है के रूप में, आप करने के लिए "unvectorise" काम पाश है और प्रत्येक बयान के ATOMIC
लागू होगा, जैसे:
!$OMP ATOMIC UPDATE
A(jj,1)=A(jj,1)+(M(ii)/coff)*(distance_vector(1))
!$OMP ATOMIC UPDATE
A(jj,2)=A(jj,2)+(M(ii)/coff)*(distance_vector(2))
!$OMP ATOMIC UPDATE
A(jj,3)=A(jj,3)+(M(ii)/coff)*(distance_vector(3))
तुम भी एक पाश के रूप में इस पुनर्लेखन कर सकते हैं - घोषित करने के लिए मत भूलना लूप काउंटर private
।
!$OMP CRITICAL (forceloop)
A(jj,:)=A(jj,:)+(M(ii)/coff)*(distance_vector)
!$OMP END CRITICAL (forceloop)
महत्वपूर्ण क्षेत्रों का नामकरण वैकल्पिक और थोड़ा इस विशेष मामले में अनावश्यक है लेकिन सामान्य रूप में यह असंबंधित महत्वपूर्ण क्षेत्रों को अलग करने के लिए अनुमति देता है:
CRITICAL
के साथ पाश unvectorise की कोई जरूरत नहीं है।
कौन सा तेज़ है? ATOMIC
या CRITICAL
के साथ अनलॉक किया गया? यह कई चीजों पर निर्भर करता है। आम तौर पर CRITICAL
रास्ता धीमा है क्योंकि इसमें अक्सर ओपनएमपी रनटाइम में फ़ंक्शन कॉल शामिल होते हैं, जबकि परमाणु वृद्धि, कम से कम x86 पर, लॉक किए गए अतिरिक्त निर्देशों के साथ कार्यान्वित की जाती है। जैसा कि वे अक्सर कहते हैं, वाईएमएमवी।
पुनरावृत्ति के लिए, अपने पाश में काम करने का संस्करण होना चाहिए कुछ की तरह:
!$OMP PARALLEL DO PRIVATE(jj,kk,distance_vector,distance2,distance,coff) &
!$OMP& REDUCTION(+:PE)
do ii=1,N-1
do jj=ii+1,N
distance_vector=X(ii,:)-X(jj,:)
distance2=sum(distance_vector*distance_vector)
distance=DSQRT(distance2)
coff=distance*distance*distance
PE=PE-M(II)*M(JJ)/distance
do kk=1,3
!$OMP ATOMIC UPDATE
A(jj,kk)=A(jj,kk)+(M(ii)/coff)*(distance_vector(kk))
end do
A(ii,:)=A(ii,:)-(M(jj)/coff)*(distance_vector)
end do
end do
!$OMP END PARALLEL DO
मैं मान लिया गया है कि आपके सिस्टम 3-आयामी है।
यह सब के साथ कहा, मैं दूसरी इयान बुश है कि आप पर पुनर्विचार करने के लिए कैसे स्थिति और त्वरण मैट्रिक्स स्मृति में बाहर रखी हैं की जरूरत है। उचित कैश उपयोग आपके कोड को बढ़ावा दे सकता है और कुछ संचालन के लिए भी अनुमति देगा, उदा। X(:,ii)-X(:,jj)
वेक्टरिज्ड होने के लिए, यानी वेक्टर सिम निर्देशों का उपयोग करके कार्यान्वित किया गया।
शुक्रिया, फिर से धन्यवाद। बस एक बहुत ही बुनियादी सवाल - सरल लूप के लिए यह जटिल क्यों होना चाहिए। मेरा मतलब है कि आप सिर्फ बाहरी लूप को नाथ्रेड तरीके से विभाजित करना चाहते हैं और कुछ मैट्रिक्स को पॉप्युलेट करना चाहते हैं (कम से कम मेरे द्वारा किए गए सामान में)। मैं देख सकता हूँ तुम क्यों जटिल मामलों के लिए निजी आदि की जरूरत है और इसलिए यह 'अतिरिक्त इंजीनियरिंग' लेकिन क्यों सिर्फ राज्य नहीं! $ OMP parallell डीओ साझा (मैट्रिक्स) तो यह सिर्फ N/nthreads विभाजन और उद्धार का एक फूलदान है। प्रत्येक धागे में सब कुछ अनुक्रम में किया जाएगा। मुझे लगता है कि मैं सोच रहा हूं - डिफ़ॉल्ट रूप से सब कुछ निजी क्यों नहीं बनाते, साझा नहीं किया गया है, फिर साझा करें। – Griff
@ ग्रिफ, सी/सी ++ में इन चरों को सबसे नीचे लूप के अंदर घोषित किया जा सकता है और फिर वे स्वचालित रूप से निजी होते हैं। वे साझा किए जाते हैं सीरियल कोड के ओपनएमपी मैच के अर्थशास्त्र की इच्छा से उपजी है। वैसे, आप एटोमिक्स से छुटकारा मिल सकता है अगर आप न्यूटन के तीसरे नियम के बारे में एक पल के लिए भूल जाते हैं और दोनों पाश, n' 'एक (ii के लिए काम के साथ' 1 से अधिक चलाने के लिए, :) 'केवल (अप्रभावी है)। –
क्या वैसे भी मैं आपको जांचने के लिए एक प्रश्न के रूप में पोस्ट करने के बिना आपको एक नया कोड दिखा सकता हूं? यह कुछ हद तक आसान है, लेकिन लंबा है और मैं केवल यह सुनिश्चित करना चाहता हूं कि मैं इसे शब्दों में सही तरीके से समझूं। धन्यवाद। – Griff