2010-02-28 17 views
9

में निजी है यह सुनिश्चित करने के लिए कि मैं एक लिनक्स मशीन पर जीसीसी का उपयोग कर ओपनएमपी के साथ सी में काम कर रहा हूं। लूप के समानांतर ओपनएमपी में, मैं एक स्थिर रूप से आवंटित सरणी को निजी के रूप में घोषित कर सकता हूं। कोड खंड पर विचार करें:कैसे गतिशील रूप से आवंटित सरणी ओपनएम

int a[10]; 
#pragma omp parallel for shared(none) firstprivate(a) 
for(i=0;i<4;i++){ 

और सब कुछ अपेक्षित काम करता है। लेकिन अगर बजाय मैं आवंटित एक गतिशील,

int * a = (int *) malloc(10*sizeof(int)); 
#pragma omp parallel for shared(none) firstprivate(a) 

के मूल्यों एक (कम से कम एक [1 ... 9]) सुरक्षित नहीं हैं, लेकिन अधिनियम के रूप में यदि वे साझा कर रहे हैं। यह समझ में आता है क्योंकि प्रज्ञा कमांड में कुछ भी नहीं कहता है कि एआरपी कितनी बड़ी है जिसे निजी होने की जरूरत है। मैं इस जानकारी को openmp में कैसे पास कर सकता हूं? मैं पूरे गतिशील रूप से आवंटित सरणी को निजी के रूप में कैसे घोषित करूं?

उत्तर

12

मुझे नहीं लगता कि आप ऐसा करते हैं - मैंने इस समस्या को हल करने के लिए क्या किया था, समानांतर क्षेत्र #pragma omp parallel shared(...) private(...) का उपयोग किया गया था और समानांतर क्षेत्र के अंदर गतिशील रूप से सरणी आवंटित की गई थी। इस प्रयास करें:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test2 -fopenmp test2.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 
    int* c; 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel shared(a,b) private(c,i) 
    { 
     c = (int*) calloc(3, sizeof(int)); 

     #pragma omp for 
     for (i = 0; i < size; i++) 
     { 
      c[0] = 5*a[i]; 
      c[1] = 2*b[i]; 
      c[2] = -2*i; 
      a[i] = c[0]+c[1]+c[2]; 

      c[0] = 4*a[i]; 
      c[1] = -1*b[i]; 
      c[2] = i; 
      b[i] = c[0]+c[1]+c[2]; 
     } 

     free(c); 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

मुझे मेरी पहले प्रयोग कार्यक्रम के रूप में एक ही परिणाम का उत्पादन किया है कि:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

/* compile with gcc -o test1 -fopenmp test1.c */ 

int main(int argc, char** argv) 
{ 
    int i = 0; 
    int size = 20; 
    int* a = (int*) calloc(size, sizeof(int)); 
    int* b = (int*) calloc(size, sizeof(int)); 

    for (i = 0; i < size; i++) 
    { 
     a[i] = i; 
     b[i] = size-i; 
     printf("[BEFORE] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 

    #pragma omp parallel for shared(a,b) private(i) 
    for (i = 0; i < size; i++) 
    { 
     a[i] = 5*a[i]+2*b[i]-2*i; 
     b[i] = 4*a[i]-b[i]+i; 
    } 

    for (i = 0; i < size; i++) 
    { 
     printf("[AFTER] At %d: a=%d, b=%d\n", i, a[i], b[i]); 
    } 
} 

एक अनुमान मैं कहना चाहता हूँ क्योंकि OpenMP यह कर सकते हैं सरणी के आकार अनुमान नहीं कर सकते पर निजी नहीं होगा - केवल संकलन-समय सरणी इस तरह से की जा सकती हैं। जब मैं एक्सेस उल्लंघन के कारण संभावित रूप से आवंटित आवंटित सरणी को निजी करने की कोशिश करता हूं तो मुझे segfaults मिलते हैं। प्रत्येक थ्रेड पर सरणी आवंटित करना जैसे कि आप इसे pthreads का उपयोग करके लिखते हैं, समझ में आता है और समस्या हल करता है।

+0

धन्यवाद, ओपनएमपी घोषणा को अलग करना और घोषणा के लिए समानांतर पूरी तरह से काम करता है। – cboettig

+0

@Ninefingers: मुझे पता है कि यह पोस्ट पुराना है, लेकिन मेरे पास एक त्वरित सवाल था। क्या आपको बयान के लिए '#pragma omp' की भी आवश्यकता है? क्या यह समानांतर में समानांतर में लूप नहीं करेगा? – Amit

+1

@ प्रवेश न करें, आपको थ्रेड को तोड़ने के लिए कंपाइलर को बताना होगा, अन्यथा यह नहीं होगा। –

6

आपने ओपनएमपी को बताया कि पॉइंटरa निजी है, यानी प्रत्येक थ्रेड में दोहराया गया है। आपकी सरणी कुछ मनमाने ढंग से डेटा a अंक है, और ओपनएमपी इसे दोहराना नहीं करेगा (शायद क्योंकि यह दोहराए गए सरणी आवंटित और रद्द करने के लिए आवश्यक होगा)।

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