2015-03-26 6 views
5

के साथ सरणी तत्वों की समानांतर वृद्धि, मेरे पास आकार संख्या के सरणी a है यादृच्छिक संख्या के साथ। OpenMP का उपयोग करते हुए मैं तत्वों ए में हर नंबर के लिए आकार 10 की सरणी b के 9 को 0 बढ़ाने के लिए भाषा चाहते सीओपनएमपी

है
#pragma omp parallel for 
for(i = 0; i < N; i++) 
    b[a[i]]++; 

दुर्भाग्य ख के कुछ तत्वों में जाहिरा तौर पर simultanous राईट देखते हैं और परिणाम नहीं है जैसा सोचा था। मैंने बी को पहली बार और आखिरी बार स्थापित करने की कोशिश की लेकिन इससे कोई मदद नहीं मिली।

कार्य आसान लगता है लेकिन मुझे नहीं पता कि इसे कैसे करें क्योंकि ओपनएमपी में सरणी के लिए atomic नहीं है। मैं धागे की संख्या के लिए एक नई सरणी बना सकता हूं और फिर अंत में उन्हें एक साथ जोड़ सकता हूं लेकिन यह इष्टतम प्रतीत नहीं होता है।

सरणी b के तत्वों में a में संख्याओं के अवसरों की गणना करने का सबसे तेज़ तरीका कौन सा होगा?

+2

योग है स्वतंत्र रूप से और फिर परिणामों मर्ज करें। –

+1

@BrianCain मुझे यकीन नहीं है कि आप वास्तव में क्या मतलब है। 'योग' के साथ क्या आप वृद्धि का मतलब है? 'स्वतंत्र रूप से' के साथ आपका मतलब है कि मुझे एक नया निजी चर बनाना चाहिए? विलय के साथ आपका मतलब है कि मुझे अंत में निजी चर के सभी संस्करणों को जोड़ना चाहिए? क्योंकि यह मेरे लिए अक्षम लगता है। क्या आप मुझे एक साधारण कोड खंड के साथ दिखा सकते हैं जिसका मतलब है? – Michael

+0

एल्गोरिदम उतना आसान नहीं है जितना मैंने माना था। लेकिन आखिरकार यह एक ट्रेडऑफ है और क्या यह संभवतः एन से 'बी 'के आकार के अनुपात पर निर्भर करता है (क्या यह वास्तव में हमेशा 10 है?)। म्यूटेक्स की श्रृंखला का उपयोग करना एक आसान विकल्प है। –

उत्तर

0

यदि किसी [] में कोई भी मान समान है तो आप एक ही तत्व के साथ एक साथ लिखेंगे।

एक [0] = 1 और एक [1] = 1 तो आप एक ही समय में बी [1] पर लिखेंगे।

0

आप "के लिए()" प्रत्येक सरणी

+0

यह एक टिप्पणी होना चाहिए – codingadventures

2

आपका प्रश्न अनिवार्य रूप से एक सवाल मैं fill-histograms-in-parallel-with-openmp-without-using-a-critical-section पूछा का डुप्लिकेट है के लिए एक 2 का उपयोग कर सकते हैं।

अपने मामले में आसान समाधान

#pragma omp parallel 
{ 
    int i, b_local[10] = {0}; 
    #pragma omp for nowait 
    for(i = 0; i < n; i++) b_local[a[i]]++; 
    #pragma omp critical 
    for(i=0; i<10; i++) b[i] += b_local[i];  
} 

यह एक महत्वपूर्ण खंड के बिना यह करने के लिए (मेरे सवाल देखें) संभव है, लेकिन यह जरूरी नहीं कि और अधिक कुशल नहीं है।

यहाँ एक काम कर उदाहरण

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

#define N 100 

void foo(int *b, int *a, int n) { 
    #pragma omp parallel 
    { 
     int i, b_local[10]; 
     memset(b_local, 0, 10*sizeof(int)); 
     #pragma omp for 
     for(i = 0; i < n; i++) b_local[a[i]]++; 


     #pragma omp critical 
     {  
      for(i=0; i<10; i++) { 
       b[i] += b_local[i]; 
      } 
     } 

    } 
} 

int main() { 
    int i; 
    int b[10] = {0,1,2,3,4,5,6,7,8,9}; 
    int b2[10] = {0,1,2,3,4,5,6,7,8,9}; 
    int a[N]; 
    for(i=0; i<N; i++) a[i] = rand()%10; 

    foo(b,a,N); 
    for(i=0; i<N; i++) b2[a[i]]++; 
    for(i=0; i<10; i++) printf("%d ", b[i]); puts(""); 
    for(i=0; i<10; i++) printf("%d ", b2[i]); puts(""); 
} 
संबंधित मुद्दे