2014-04-08 12 views
6

मैं पिछले कुछ दिनों में एक अजीब समस्या का सामना कर रहा हूं। हम जीसीसी 4.8 का उपयोग करके कुछ पुस्तकालय बनाते हैं जो उनकी कुछ निर्भरताओं को स्थिर रूप से लिंक करते हैं - उदाहरण के लिए। log4cplus या बढ़ावा। इन पुस्तकालयों के लिए हमने बूथ-पायथन का उपयोग करके पाइथन बाइंडिंग बनाई हैं।ओपनएमपी को जोड़ने के बीच अंतर- fopenmp और -lgomp

हर बार ऐसी लाइब्रेरी टीएलएस का उपयोग करती है (जैसे log4cplus इसके स्थिर प्रारंभ में होता है या stdlibC++ अपवाद फेंकने पर करता है - न केवल प्रारंभिक चरण के दौरान) पूरी चीज एक segfault में दुर्घटनाग्रस्त हो जाती है - और हर बार स्थानीय थ्रेड का पता परिवर्तनीय 0.

मैंने पुन: संयोजन की तरह सब कुछ करने की कोशिश की, सुनिश्चित करने के लिए -एफपीआईसी का उपयोग किया जाता है, सुनिश्चित करने के लिए -tls-model = वैश्विक-गतिशील उपयोग किया जाता है, आदि कोई सफलता नहीं। फिर आज मुझे पता चला कि इन दुर्घटनाओं का कारण ओपनएमपी को जोड़ने का हमारा तरीका रहा है। हमने इसे "-fopenmp" का उपयोग करने के बजाय "-lgomp" का उपयोग करके किया था। चूंकि मैंने यह सब बदल दिया है ठीक है - कोई दुर्घटना नहीं, कुछ भी नहीं। ठीक!

लेकिन मैं वास्तव में जानना चाहता हूं कि समस्या का कारण क्या था। तो ओपनएमपी में जोड़ने के लिए इन दो संभावनाओं के बीच क्या अंतर है?

हमारे पास एक सेंटोस 5 मशीन है जहां हमने एक जीसीसी -4.8/ऑप्ट/लोकल/जीसीसी 48 में स्थापित किया है और हम यह भी सुनिश्चित कर रहे हैं कि/opt/local/gcc48 से आने वाले libgomp का उपयोग किया गया था साथ ही libstdC++ वहां से (DL_DEBUG प्रयुक्त)।

कोई विचार? Google पर कुछ भी नहीं मिला - या मैंने गलत कीवर्ड का उपयोग किया :)

+0

-pthread या -lpthread वहां – duselbaer

+1

'-v' के साथ संकलित किया गया था और आउटपुट की तुलना करें ... –

+1

लिंकर विकल्प के रूप में -v जोड़ना दिखाता है कि -फॉपेंम्प अंत में एक -lgomp जोड़ता है। बाकी सब कुछ वही रहता है। बिना -fopenp मेरे पास है "-lstdC++ -lm -lgcc_s -lpthread -lc -lgcc_s" और -fopenmp यह हो जाता है "-lstdC++ -lm -lgomp -lgcc_s -lpthread -lc -lgcc_s" के साथ। मैं अभी भी दुर्घटनाओं का कारण नहीं दिख रहा है क्योंकि इन पुस्तकालयों के सभी जुड़े हुए हैं गतिशील :( – duselbaer

उत्तर

6

ओपनएमपी आपके कोड और उसके निष्पादन के बीच मध्यस्थ है। प्रत्येक #pragma omp कथन को उनके ओपनएमपी लाइब्रेरी फ़ंक्शन के अनुसार कॉल में परिवर्तित कर दिया जाता है, और यह सब कुछ है। बहुप्रचारित निष्पादन (थ्रेड लॉन्च करना, उन्हें शामिल करना और सिंक्रनाइज़ करना आदि) हमेशा ऑपरेटिंग सिस्टम (ओएस) द्वारा संभाला जाता है। सभी ओपनएमपी इन छोटे-स्तर के ओएस-निर्भर थ्रेडिंग कॉल को हमारे लिए एक छोटे और मीठे इंटरफ़ेस में पोर्टेबल रूप से प्रबंधित कर रहा है।

-fopenmp ध्वज एक उच्च स्तरीय है जो जीसीसी के ओपनएमपी कार्यान्वयन (gomp) को शामिल करने से अधिक करता है। इस गोम्प लाइब्रेरी को ओएस की थ्रेडिंग कार्यक्षमता तक पहुंचने के लिए और पुस्तकालयों की आवश्यकता होगी। पॉज़िक्स-अनुपालन ओएस पर, ओपनएमपी आमतौर पर पठ्रेड पर आधारित होता है, जिसे लिंक करने की आवश्यकता होती है। कुछ ओएस पर काम करने के लिए इसे रीयलटाइम एक्सटेंशन लाइब्रेरी (लाइब्रेट) की भी आवश्यकता हो सकती है, जबकि किसी अन्य पर नहीं। गतिशील लिंकिंग का उपयोग करते समय, सबकुछ स्वचालित रूप से खोजा जाना चाहिए, लेकिन जब आपने -static निर्दिष्ट किया है, तो मुझे लगता है कि आप Jakub Jelinek here द्वारा वर्णित स्थिति में गिर गए हैं। लेकिन आजकल, -static का उपयोग होने पर, pthread (और यदि आवश्यक हो तो आरटी स्वचालित रूप से लिंक होना चाहिए)।

निर्भरताओं को जोड़ने के अलावा, -fopenmp ध्वज कुछ प्रागमा स्टेटमेंट प्रोसेसिंग को भी सक्रिय करता है। आप पूरे जीसीसी कोड (here और here के रूप में) देख सकते हैं कि -fopenmp ध्वज के बिना (जो केवल गोम्प लाइब्रेरी को लिंक करके ट्रिगर नहीं किया जाता है), एकाधिक प्रोग्राम्स को उचित ओपनएमपी फ़ंक्शन कॉल में परिवर्तित नहीं किया जाएगा। मैंने बस कुछ उदाहरण कोड के साथ प्रयास किया, और -lgomp और -fopenmp एक कार्यकारी निष्पादन योग्य उत्पन्न करता है जो समान पुस्तकालयों के खिलाफ लिंक करता है। मेरे सरल उदाहरण में एकमात्र अंतर यह है कि -fopenmp का एक प्रतीक है कि -lgomp में यह नहीं है: [email protected]@GOMP_4.0+ (कोड here) जो फ़ंक्शन है जो मेरे उदाहरण कोड में #pragma omp parallel द्वारा अनुरोध किए गए फोर्क प्रदर्शन करने वाले समांतर अनुभाग को प्रारंभ करता है। इस प्रकार, -lgomp संस्करण ने प्रागमा को जीसीसी के ओपनएमपी कार्यान्वयन के लिए कॉल में अनुवाद नहीं किया। दोनों ने एक कार्यकारी निष्पादन योग्य उत्पादन किया, लेकिन केवल -fopenmp ध्वज ने इस मामले में समानांतर निष्पादन योग्य बनाया।

लपेट के लिए, -fopenmp सभी OpenMP pragmas कार्रवाई करने के लिए जीसीसी के लिए आवश्यक है। इसके बिना, आपके समानांतर खंड किसी थ्रेड को नहीं फेंकेंगे, जो आपके आंतरिक कोड को किए गए मान्यताओं के आधार पर विनाश को खत्म कर सकता है।

+0

अपने उदाहरण के साथ कि आप (संकलन) '-fopenmp' साथ स्रोत के निर्माण और उसके बाद के साथ जोड़ने में अपने' .o' इस्तेमाल किया '-fopenmp' /' -lgomp'? जब आप 'gcc-fopenmp example.c' का उपयोग करें, यह संकलन में omp pragma को सक्षम करेगा और लिंकिंग में लाइब्रेरी जोड़ देगा, लेकिन एकल कमांड संकलन + gcc -lgomp example.c' के रूप में लिंक संकलन और प्रज्ञा के लिए openmp-en सक्षम विकल्प को पास नहीं करेगा ओंप होगा अवहेलना करना। – osgx

+1

मैं गलत हो सकता हूं, लेकिन मुझे विश्वास है कि हम एक ही बात कह रहे हैं? मैंने लिखा "केवल' -fopenmp' एक समानांतर निष्पादन का उत्पादन करेगा "जब तुम जैसे" '-lgomp' एक समानांतर निष्पादन का उत्पादन नहीं होगा" कुछ लिखा था, या मैं कुछ याद किया? (जैसा कि मैंने लिखा था, pragmas को '-fopenmp' के बिना फ़ंक्शन कॉल में परिवर्तित नहीं किया जाएगा) किसी भी मामले में, मैंने जो कहा है उससे मैं सहमत हूं, और मेरा मानना ​​है कि उत्तर वही बात कहता है। शायद मेरे उत्तर का शब्द बेहतर हो सकता है, हालांकि ... – Soravux

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