2012-11-09 15 views
24

मुझे आश्चर्य है कि मुझे बाधा का उपयोग करने की आवश्यकता कब होगी? क्या मुझे स्कैटर से पहले/बाद में इसकी आवश्यकता है/उदाहरण के लिए इकट्ठा करें? या ओएमपीआई को यह सुनिश्चित करना चाहिए कि स्कैटर/इकट्ठा करने से पहले सभी प्रक्रियाएं उस बिंदु तक पहुंच गई हों? इसी प्रकार, प्रसारण के बाद क्या मैं उम्मीद कर सकता हूं कि सभी प्रक्रियाएं पहले ही संदेश प्राप्त कर सकें?मुझे MPI_Barrier() का उपयोग करने की आवश्यकता कब होगी?

उत्तर

21

MPI-3.0 से पहले एमपीआई में सभी सामूहिक संचालन अवरुद्ध हो रहे हैं, जिसका अर्थ है कि लौटने के बाद उन्हें पास किए गए सभी बफर का उपयोग करना सुरक्षित है। विशेष रूप से, इसका मतलब है कि इन कार्यों में से एक लौटने पर सभी डेटा प्राप्त हुआ था। (हालांकि, यह इंगित नहीं करता है कि सभी डेटा भेजा गया था!) ​​ तो सामूहिक संचालन से पहले/बाद में MPI_Barrier आवश्यक नहीं है (या बहुत उपयोगी), यदि सभी बफर पहले से ही मान्य हैं।

कृपया यह भी ध्यान दें कि MPI_Barrier गैर-अवरुद्ध कॉल के लिए जादुई रूप से प्रतीक्षा नहीं करता है। यदि आप एक गैर-अवरुद्ध प्रेषण/आरईवी का उपयोग करते हैं और दोनों प्रक्रियाएं भेजें/recv जोड़ी के बाद MPI_Barrier पर प्रतीक्षा करें, तो यह गारंटी नहीं है कि MPI_Barrier के बाद सभी डेटा भेजे गए/प्राप्त किए गए प्रक्रियाएं। इसके बजाए MPI_Wait (और दोस्तों) का प्रयोग करें। तो कोड का निम्न भाग में त्रुटियां हैं:

/* ERRORNOUS CODE */ 

Code for Process 0: 
Process 0 sends something using MPI_Isend 
MPI_Barrier(MPI_COMM_WORLD); 
Process 0 uses buffer passed to MPI_Isend // (!) 

Code for Process 1: 
Process 1 recvs something using MPI_Irecv 
MPI_Barrier(MPI_COMM_WORLD); 
Process 1 uses buffer passed to MPI_Irecv // (!) 
दोनों लाइनों कि (!) के साथ चिह्नित हैं

असुरक्षित कर रहे हैं!

MPI_Barrier केवल कुछ मामलों में उपयोगी है। अधिकांश समय आपको परवाह नहीं है कि आपकी प्रक्रियाएं सिंक हो रही हैं या नहीं। ब्लॉकिंग और गैर-अवरुद्ध कॉल के बारे में बेहतर पढ़ें!

+0

पहली '(!)' त्रुटि क्यों है? प्रक्रिया 0 में अभी भी अपना बफर होगा? इसके अलावा एक प्रेषण के बाद, प्राप्तकर्ता पार्टी इसे सही नहीं बदलेगी? –

+2

@JiewMeng MPI MPI_Isend को कॉल करने के तुरंत बाद बफर से नहीं पढ़ना चाहिए। यदि आप इसे '(!)' में बदलते हैं, तो आप कुछ अलग भेज सकते हैं। मुझे इसके बारे में बिल्कुल यकीन नहीं है, लेकिन मुझे लगता है कि इस मामले में व्यवहार अपरिभाषित है। –

+3

मैंने थोड़ा जवाब दिया है क्योंकि MPI-3.0 ने गैर-अवरुद्ध संग्रहकर्ताओं को पेश किया है। –

13

MPI_Barrier का एक उपयोग उदाहरण के लिए फाइल सिस्टम जैसे बाह्य संसाधन तक पहुंच को नियंत्रित करने के लिए है, जिसे एमपीआई का उपयोग नहीं किया जाता है। उदाहरण के लिए, यदि आप प्रत्येक प्रक्रिया अनुक्रम में एक फाइल करने के लिए सामान लिखना चाहते हैं, तो आप इसे इस तरह कर सकता है:

int rank, size; 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
for (int ii = 0; ii < size; ++ii) { 
    if (rank == ii) { 
     // my turn to write to the file 
     writeStuffToTheFile(); 
    } 
    MPI_Barrier(MPI_COMM_WORLD); 
} 

इस तरह, आप सुनिश्चित करें कि कोई दो प्रक्रियाओं समवर्ती बुला रहे हैं writeStuffToTheFile हो सकता है।

0

मई MPI_Barrier() का उपयोग अक्सर नहीं किया जाता है, लेकिन यह उपयोगी है। असल में, यदि आप सिंक्रोनस संचार का उपयोग करते थे, तो MPI_Send/Recv() केवल यह सुनिश्चित कर सकता है कि दो प्रक्रिया सिंक्रनाइज़ की गई है। मेरी परियोजना में, एक क्यूडा + एमपीआई प्रोजेक्ट, जो मैंने उपयोग किया वह असीमित संचार है। मैंने पाया कि कुछ मामलों में यदि मैं MPI_Barrier() का उपयोग प्रतीक्षा() फ़ंक्शन के बाद करता हूं, तो स्थिति दो प्रक्रियाओं (gpu) एक ही समय में एक-दूसरे को डेटा संचारित करना चाहती है, जो होने की संभावना है, जो हो सकता है प्रोग्राम दक्षता को बुरी तरह कम करें। ऊपर की बग मुझे पागल कर देती है और मुझे खोजने के लिए कुछ दिन ले जाती है। इसलिए जब आप अपने प्रोग्राम में MPI_Isend/Irecv का उपयोग करते हैं तो आप MPI_Barrier() का उपयोग सावधानी से सोच सकते हैं। कभी-कभी सिंक प्रक्रियाएं न केवल अनिवार्य है बल्कि यह भी आवश्यक है कि विशेष रूप से आपका प्रोग्राम डिवाइस से निपट रहा हो।

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