g ++

2012-08-17 9 views
16

का उपयोग करके openmp को संकलित करने के लिए मुझे openmp संकलन के बारे में कोई समस्या है।g ++

निम्नलिखित कोड की तरह

:

#include <iostream> 
#include <pthread.h> 
#include <omp.h> 
#include <semaphore.h> 
#include <stack> 
using namespace std; 
sem_t empty,full; 
stack<int> stk; 
void produce(int i) 
{ 
    { 
    sem_wait(&empty); 
      cout<<"produce "<<i*i<<endl; 
      stk.push(i*i); 
    sem_post(&full); 
    } 
} 
void consume1(int &x) 
{ 
    sem_wait(&full); 
      int data=stk.top(); 
      stk.pop(); 
      x=data; 
    sem_post(&empty); 
} 
void consume2() 
{ 
    sem_wait(&full); 
      int data=stk.top(); 
      stk.pop(); 
      cout<<"consume2 "<<data<<endl; 
    sem_post(&empty); 
} 
int main() 
{ 
    sem_init(&empty,0,1); 
    sem_init(&full,0,0); 
    pthread_t t1,t2,t3; 
    omp_set_num_threads(3); 
    int TID=0; 
    #pragma omp parallel private(TID) 
    { 
      TID=omp_get_thread_num(); 
      if(TID==0) 
      { 
      cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 
      for(int i=0;i<5;i++) 
        produce(i); 
      } 
      else if(TID==1) 
      { 
        int x; 
        while(true) 
        { 
          consume1(x); 
          cout<<"consume1 "<<x<<endl; 
        } 
      } 
      else if(TID==2) 
      { 
        int x; 
        while(true) 
        { 
          consume1(x); 
          cout<<"consume2 "<<x<<endl; 
        } 
      } 
    } 
    return 0; 
} 

सबसे पहले, मैं इसे का उपयोग कर संकलन:

g++ test.cpp -fopenmp -lpthread 

और, मैं सही जवाब मिल गया है, वहाँ 3 धागे पूरी तरह से कर रहे हैं।

लेकिन, जब मैं इस तरह संकलन कार्य करें:

g++ -c test.cpp -o test.o 
g++ test.o -o test -fopenmp -lpthread 

सिर्फ केवल एक धागा है।

कोई भी मुझे बता सकता है कि इस कोड को सही तरीके से कैसे संकलित करें। पहले ही, आपका बहुत धन्यवाद।

+3

मुझे लगता है कि ओपनएमपी प्रागम्स को तब तक अनदेखा किया जाता है जब तक आपके पास '-फॉपेंम्प' न हो। इसलिए आपको ओपनएमपी प्रोग्राम्स वाले सभी मॉड्यूल पर '-फॉपेंम्प' की आवश्यकता होगी। – Mysticial

+0

@ मैस्टिसियल आपको लगता है कि जब मैं .cpp को .o फ़ाइल संकलित करता हूं तो मुझे -fopenmp जोड़ना चाहिए? –

+1

हाँ। 'G ++ -c test.cpp -o test.o -fopenmp' आज़माएं। अगर यह काम करता है तो मैं इसे उत्तर दूंगा। – Mysticial

उत्तर

15

ओपनएमपी प्रागमा केवल -fopenmp के साथ संकलित किए जाने पर सक्षम हैं। अन्यथा वे पूरी तरह से संकलक द्वारा अनदेखा कर रहे हैं। (इसलिए, केवल 1 धागा ...)

इसलिए, आपको ओपनएमपी का उपयोग करने वाले प्रत्येक मॉड्यूल के संकलन के लिए -fopenmp जोड़ने की आवश्यकता होगी। (सिर्फ अंतिम जोड़ने चरण के लिए। का विरोध के रूप में)

g++ -c test.cpp -o test.o -fopenmp 
g++ test.o -o test -fopenmp -lpthread 
22

OpenMP pragmas, यानी वे केवल संकलन समय पर लागू होते हैं बदलने कोड का एक सेट है। आप कोड संकलन को पहले से संकलित ऑब्जेक्ट कोड पर लागू नहीं कर सकते हैं (ठीक है, आप कर सकते हैं, लेकिन यह प्रक्रिया में बहुत अधिक शामिल है और इन दिनों अधिकांश कंपेलर क्या करते हैं इसके दायरे से बाहर है)। लिंकर चरण के दौरान आपको केवल -fopenmp की आवश्यकता होती है, केवल संकलक के लिए ओपनएमपी रनटाइम लाइब्रेरी libgomp से स्वचालित रूप से लिंक करने के लिए - यह ऑब्जेक्ट कोड के लिए कुछ और नहीं करता है।

एक तरफ ध्यान दें, हालांकि तकनीकी रूप से सही है, आपका कोड ओपनएमपी को बहुत ही गैर-ओपनएमपी तरीके से करता है। सबसे पहले, आपने OpenMP sections निर्माण को फिर से कार्यान्वित किया है। अपने main समारोह में समानांतर क्षेत्र में एक और अधिक OpenMP तरह से फिर से लिखा जा सकता है:

#pragma omp parallel sections 
{ 
    #pragma omp section 
    { 
     cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 
     for(int i=0;i<5;i++) 
      produce(i); 
    } 
    #pragma omp section 
    { 
     int x; 
     while(true) 
     { 
      consume1(x); 
      cout<<"consume1 "<<x<<endl; 
     } 
    } 
    #pragma omp section 
    { 
     int x; 
     while(true) 
     { 
      consume1(x); 
      cout<<"consume2 "<<x<<endl; 
     } 
    } 
} 

(यदि आप SIGILL प्राप्त तीन से अधिक OpenMP धागे के साथ इस कोड चलाते समय आप जीसीसी में एक बग, कि हो जाएगा सामना करना पड़ा आगामी रिलीज में तय)

दूसरा, आप ओपनएमपी task निर्माण पर एक नज़र डालना चाहेंगे। इसके साथ आप किसी भी निष्क्रिय थ्रेड द्वारा कार्यों के रूप में समवर्ती रूप से निष्पादित करने के लिए कोड के टुकड़े कतार कर सकते हैं। दुर्भाग्य से इसे एक कंपाइलर की आवश्यकता होती है जो ओपनएमपी 3.0 का समर्थन करता है, जो समीकरण से एमएसवीसी ++ का नियम बनाता है, लेकिन केवल तभी जब आप विंडोज़ के लिए पोर्टेबिलिटी की परवाह करते हैं (और आप स्पष्ट रूप से नहीं करते हैं, क्योंकि आप पॉज़िक्स थ्रेड का उपयोग कर रहे हैं)।

+3

+1 वास्तव में ओपी के कोड को अधिक बारीकी से देखने का कर्तव्य है। – Mysticial