2013-07-10 7 views
7

का उपयोग कर "अमान्य नियंत्रण भविष्यवाणी" संकलक त्रुटि C - determine if a number is prime पर आधारित, लेकिन मैं ओपनएमपी का उपयोग कर मूलभूत प्राइम नंबर चेकर बना रहा हूं।ओपनएमपी

int isPrime(int value) 
{ 
    omp_set_num_threads(4); 

    #pragma omp parallel for 
    for(int j = 2; j * j <= value; j++) 
    { 
    if (value % j == 0) return 0; 
    } 
    return value; 
} 

जब -fopenmp साथ संकलन, जीसीसी संस्करण 4.7.2 erroring है, पाश के लिए के संबंध में invalid controlling predicate बताते हुए।

ऐसा लगता है कि यह त्रुटि लूप में जे वर्ग के कारण होती है। क्या कोई तरीका है कि मैं इसके आसपास काम कर सकता हूं और अभी भी एल्गोरिदम से वांछित आउटपुट प्राप्त कर सकता हूं?

+0

क्या आप सुनिश्चित हैं कि खुले एमपी लूप निर्माण में वापसी कथन की अनुमति है? – alexbuisson

+0

दुर्भाग्य से, ओपनएमपी के साथ लूप समानांतर परीक्षण परीक्षण के साथ एक ही प्राइम के परीक्षण के लिए मदद नहीं करेगा। हालांकि, आप परीक्षण प्रभाग का उपयोग करके कई प्राइम्स के परीक्षण के लिए प्रभावी ढंग से इसका उपयोग कर सकते हैं। हालांकि, primes की सूचियों को खोजने के लिए मैं Eratosthenes की चलनी की सलाह देते हैं। ओपनएमपी http://create.stephan-brumme.com/eratosthenes/ –

+0

का उपयोग करके एक संस्करण यहां दिया गया है, इसके अलावा, आपके 'isPrime' फ़ंक्शन में मैं 'j * j/value' के बजाय 'j <= j/value' का उपयोग करने की अनुशंसा करता हूं। जो http://rosettacode.org/wiki/Primality_by_trial_division#C –

उत्तर

8

return लूप के अंदर अनुमति नहीं है क्योंकि यह घुंघराले ब्रेसिज़ से पहले बाहर निकल जाएगा।

नोट परिभाषा नीचे दिए गए:

OpenMP V2.5 कल्पना से, 1.2.2 OpenMP भाषा शब्दावली, p2: 17-

संरचित ब्लॉक - सी/सी के लिए ++, एक निष्पादन योग्य बयान , संभावित रूप से यौगिक, शीर्ष पर एक प्रविष्टि के साथ और नीचे एक एकल निकास के साथ।

एक संरचित ब्लॉक खुले { के साथ शुरू होता है और समापन } के साथ समाप्त होता है। return इन ब्रेसिज़ के भीतर निहित है, इसलिए है क्योंकि यह दो रास्ते (return से कम एक और ब्रेस के माध्यम से बाहर निकलने में एक)

OpenMP स्थानों निम्नलिखित पांच प्रतिबंध है इस कार्यक्रम भी एक संरचित ब्लॉक के लिए OpenMP परिभाषा का उल्लंघन करती है, जिस पर लूप को थ्रेड किया जा सकता है:

  • लूप चर प्रकार हस्ताक्षरित पूर्णांक होना चाहिए। बिना हस्ताक्षर किए गए पूर्णांक, जैसे कि DWORD, काम नहीं करेंगे।
  • तुलना आपरेशन रूप loop_variable में होना चाहिए <, <=, >, या >= loop_invariant_integer
  • पाश के लिए के तीसरे अभिव्यक्ति या वेतन वृद्धि भाग या तो पूर्णांक अलावा या पूर्णांक घटाव होना चाहिए और एक पाश द्वारा अपरिवर्तनीय मूल्य।
  • तो तुलना आपरेशन < या <= है, पाश चर हर यात्रा पर वेतन वृद्धि, और इसके विपरीत, अगर तुलना आपरेशन > या >= है, पाश चर हर यात्रा पर घटती करना चाहिए।
  • लूप एक मूल ब्लॉक होना चाहिए, जिसका मतलब के अंदर से कोई भी कूद नहीं है, बाहर के लूप को कथन के अपवाद के साथ अनुमति है, जो पूरे एप्लिकेशन को समाप्त करता है। यदि बयान गोटो या ब्रेक का उपयोग किया जाता है, तो उन्हें के बाहर नहीं, लूप के भीतर कूदना होगा। अपवाद हैंडलिंग के लिए भी यही है; लूप के भीतर अपवादों को पकड़ा जाना चाहिए।
+0

अतिप्रवाह हो सकता है मुझे समझ में नहीं आता कि लूप चर पर हस्ताक्षर क्यों किया जाना चाहिए। यदि आपको हस्ताक्षरित 8 बाइट नंबर से अधिक पूर्णांक की आवश्यकता है तो क्या होगा? – Nubcake

2

ओपनएमपी मानक (§2.5.1, पी।40), for पाश को नियंत्रित करने विधेय के स्वीकार्य प्रकार हैं:

  • वर रिलेशनल-op b, और
  • ख रिलेशनल-op वर

का आपके द्वारा उपयोग j * j <= value इस आवश्यकता का स्पष्ट उल्लंघन है। तर्क यह है कि इसे संकलक को कोड को उत्सर्जित करने की आवश्यकता होती है जो value के पूर्णांक वर्ग रूट को रन टाइम पर गणना करता है, बाद में value के कुछ मानों के लिए अनिर्धारित किया जाता है, खासकर नकारात्मक वाले लोगों के लिए।

आप j <= sqrt_value, जहां sqrt_valuevalue के पूर्णांक वर्गमूल है साथ j * j <= value की जगह ले सकता है, लेकिन फिर पाश अंदर संरचित ब्लॉक में एक विकल्प के लिए बाहर निकलें पथ होने के साथ समस्या आएगी। दुर्भाग्यवश इस मामले में कोई आसान समाधान मौजूद नहीं है क्योंकि ओपनएमपी समांतर लूप की समय-समय पर समाप्त होने का समर्थन नहीं करता है।

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