2009-06-09 14 views
6

पहले से ही यह question पढ़ना है, मुझे उचित रूप से निश्चित है कि एक ही इनपुट के साथ अस्थायी बिंदु (एक ही हार्डवेयर पर, उसी कंपाइलर के साथ संकलित) के साथ अस्थायी बिंदु का उपयोग करने वाली एक दी गई प्रक्रिया होनी चाहिए नियतात्मक। मैं एक ऐसे मामले को देख रहा हूं जहां यह सच नहीं है और यह निर्धारित करने की कोशिश कर रहा है कि इसका क्या कारण हो सकता है।फ्लोटिंग पॉइंट त्रुटियों को उत्पन्न करने के लिए एक निर्धारक प्रक्रिया का कारण क्या हो सकता है

मैंने निष्पादन योग्य संकलित किया है और मैं इसे एक ही मशीन (गैर-बहुप्रचारित) पर चल रहे सटीक डेटा को खिला रहा हूं, लेकिन मुझे लगभग 3.814697265625e-06 की त्रुटियां मिल रही हैं, जो मुझे मिली सावधानीपूर्वक चलने के बाद वास्तव में 1/4^9 = 1/2^18 = 1/262144 के बराबर है। जो 32-बिट फ्लोटिंग पॉइंट नंबर (विकिपीडिया के अनुसार लगभग 7 अंक) के सटीक स्तर के करीब है

मेरा संदेह यह है कि कोड पर लागू होने वाले अनुकूलन के साथ इसका कुछ संबंध है। मैं इंटेल सी ++ कंपाइलर का उपयोग कर रहा हूं और सुरक्षित या सख्त के बजाय फ्लोटिंग पॉइंट अटकलों को तेज़ कर दिया है। क्या यह एक फ्लोटिंग पॉइंट प्रक्रिया गैर-निर्धारिती बना सकता है? क्या अन्य अनुकूलन इत्यादि हैं जो इस व्यवहार को जन्म दे सकती हैं?

EDIT: पैक्स के सुझाव के अनुसार मैंने फ़्लोटिंग पॉइंट अनुमान के साथ कोड को फिर से संकलित किया और सुरक्षित परिणाम प्राप्त कर रहा हूं। यह मुझे इस प्रश्न को स्पष्ट करने की अनुमति देता है - वास्तव में फ़्लोटिंग-पॉइंट-अटकलें वास्तव में क्या करती हैं और सटीक उसी इनपुट पर लागू होने पर अलग-अलग परिणाम उत्पन्न करने के लिए यह एक ही बाइनरी (यानी एक संकलन, एकाधिक रन) का कारण कैसे बन सकता है?

@ बेन मैं इंटेल (आर) सी ++ 11.0.061 [आईए -32] का उपयोग करके संकलित कर रहा हूं और मैं इंटेल क्वाडकोर प्रोसेसर पर चल रहा हूं।

+0

प्रोसेसर प्रोसेसर और क्या कंपाइलर? .. कृपया – Ben

+0

यदि आपने यह पता लगाया है कि कौन सा ध्वज इसका कारण बन रहा है, तो क्यों न केवल कंपाइलर दस्तावेज़ों की जांच करें? –

+0

@ टाल - मुझे प्रलेखन से कुछ भी पता लगाने में कठिनाई हो रही है (यह केवल तेज कहता है कि एफपीएस सक्षम है और सुरक्षित/सख्त इसे अक्षम करता है)। सबसे अच्छा मैं इसे समझ सकता हूं, एफपीएस संचालन के पुनर्गठन की अनुमति देता है (ए * सी + बी * सी => सी * (ए + बी)) लेकिन ये समय अनुकूलन संकलित कर रहे हैं, जिसके परिणामस्वरूप बाइनरी अभी भी निर्धारक होनी चाहिए और मुझे वाकई पसंद आएगा यह जानने के लिए कि यह क्यों नहीं है। –

उत्तर

13

लगभग किसी भी स्थिति में जहां एक तेज मोड और एक सुरक्षित मोड है, तो आपको किसी प्रकार का व्यापार-बंद मिलेगा। अन्यथा सब कुछ तेजी से सुरक्षित मोड में चला जाएगा :-)।

और, यदि आपको एक ही इनपुट के साथ अलग-अलग परिणाम मिल रहे हैं, तो आपकी प्रक्रिया निर्धारिती नहीं है, इससे कोई फर्क नहीं पड़ता कि आप कितना मानते हैं (अनुभवजन्य साक्ष्य के बावजूद)।

मैं कहूंगा कि आपकी व्याख्या सबसे अधिक संभावना है। इसे सुरक्षित मोड में रखें और देखें कि गैर-निर्धारणा दूर हो जाती है या नहीं। यह आपको निश्चित रूप से बताएगा।

क्या अन्य अनुकूलन हैं, यदि आप एक ही कंपाइलर/लिंकर के साथ उसी हार्डवेयर पर संकलित कर रहे हैं और उन उपकरणों के लिए समान विकल्प, यह समान कोड उत्पन्न करना चाहिए। मुझे तेज मोड (या ब्रह्मांडीय किरणों के कारण स्मृति में थोड़ा सड़ांध) के अलावा कोई अन्य संभावना नहीं दिखाई दे रही है, लेकिन यह बहुत ही असंभव है)।

अपने अद्यतन करें:

  • reassociation:

    इंटेल एक दस्तावेज here जो बातें वे सुरक्षित मोड में ऐसा करने की अनुमति नहीं कर रहे हैं में से कुछ बताते हैं, सहित, लेकिन तक सीमित नहीं हैं: (a+b)+c -> a+(b+c)

  • शून्य तह: x + 0 -> x, x * 0 -> 0
  • पारस्परिक गुणा: a/b -> a*(1/b)

जबकि आप कहते हैं कि ये ऑपरेशन संकलित-समय परिभाषित हैं, इंटेल चिप्स बहुत प्यारे चालाक हैं।वे मल्टी-सीपीयू सेट-अप में पाइपलाइनों को पूर्ण रखने के लिए निर्देशों को फिर से ऑर्डर कर सकते हैं, जब तक कि कोड विशेष रूप से इस तरह के व्यवहार को प्रतिबंधित न करे, चीजें पूर्ण गति से चलने के लिए रन-टाइम (संकलन-समय नहीं) पर बदल सकती हैं।

यह उस लिंक किए गए दस्तावेज़ के पृष्ठ 15 पर शामिल है (संक्षेप में) वेक्टरेशन ("समस्या के बारे में बात करता है: अलग-अलग परिणाम उसी प्रोसेसर पर उसी डेटा पर उसी बाइनरी को फिर से चला रहे हैं")।

मेरी सलाह यह तय करना होगा कि आपको कच्चे grunt या परिणामों की कुल पुनरुत्पादन की आवश्यकता है और फिर उस पर आधारित मोड का चयन करें।

+0

अच्छी व्याख्या और संसाधनों के लिए धन्यवाद। आपके द्वारा लिंक किया गया दस्तावेज़ यह बताता है कि यह समस्या (जहां वैश्विक स्टैक पता और संरेखण वर्तमान में चल रही प्रक्रिया के बाहर की घटनाओं के कारण बदल सकता है) इंटेल कंपाइलर्स की 11.x श्रृंखला (जिसे मैं उपयोग कर रहा हूं) में तय किया गया है। हालांकि मुझे लगता है कि आपने शायद इस जवाब पर हिट किया है कि एकाधिक सीपीयू और कई खुले अनुप्रयोगों के साथ चलते समय कुछ प्रकार के निर्देश पुन: क्रमबद्ध होते जा रहे हैं। एक बार फिर धन्यवाद। –

0

यदि आपका प्रोग्राम समांतर है, क्योंकि यह क्वाड कोर पर चल सकता है, तो यह गैर-निर्धारक भी हो सकता है।

कल्पना कीजिए कि आपके पास 4 प्रोसेसर एक ही स्मृति स्थान पर एक फ़्लोटिंग पॉइंट मान जोड़ रहे हैं। तो फिर तुम

(((InitialValue+P1fp)+P2fp)+P3fp)+P4fp 

या

(((InitialValue+P2fp)+P3fp)+P1fp)+P4fp 

या अन्य संभावित orderings के किसी भी मिल सकता है।

ओह, तुम भी

InitialValue+(P2fp+P3fp)+(P1fp+P4fp) 

मिल सकता है अगर संकलक काफी अच्छा है।

दुर्भाग्यवश, फ़्लोटिंग पॉइंट जोड़ कम्यूटिव या सहयोगी नहीं है। वास्तविक संख्या अंकगणितीय है, लेकिन गोल करने, ओवरफ्लो और अंडरफ्लो के कारण फ्लोटिंग पॉइंट नहीं है।

इस वजह से, समांतर एफपी गणना अक्सर गैर-निर्धारिती होती है। "अक्सर", क्योंकि प्रोग्राम हैं जो की तरह

on each processor 
    while(there is work to do) { 
     get work 
     calculate result 
     add to total 
    } 

देखो, गैर नियतात्मक होगा, क्योंकि समय की राशि है कि प्रत्येक लेता है व्यापक रूप से भिन्न हो सकते हैं - आप आपरेशन के क्रम अनुमान नहीं लगा सकते। (खराब अगर धागे इंटरैक्ट करते हैं।)

लेकिन हमेशा नहीं, क्योंकि समानांतर प्रोग्रामिंग की शैलियों निश्चित हैं।

बेशक, कितने लोग जो निर्धारणा के बारे में परवाह करते हैं, समस्या से बचने के लिए पूर्णांक या निश्चित बिंदु में काम करते हैं। मैं सुपरक्यूम्युलेटर, 512, 1024, या 2048 बिट संख्याओं का विशेष रूप से शौकीन हूं, जो फ्लोटिंग पॉइंट नंबरों को गोल करने में त्रुटियों के बिना जोड़ा जा सकता है।


एक थ्रेडेड एप्लिकेशन के लिए: संकलक कोड को पुनर्व्यवस्थित कर सकता है। विभिन्न संकलन अलग-अलग उत्तर दे सकते हैं। लेकिन किसी विशेष बाइनरी निर्धारक होना चाहिए।

जब तक ... आप गतिशील भाषा में काम नहीं कर रहे हैं। यह अनुकूलन निष्पादित करता है जो एफपी गणनाओं को पुन: व्यवस्थित करता है, जो समय के साथ भिन्न होता है।

या जब तक ... वास्तव में लंबे समय तक शॉट नहीं: इटेनियम में एएलएटी की तरह कुछ विशेषताएं थीं, जिसने एकल थ्रेड किए गए कोडेड गैर-निर्धारिती भी बनाये। आप इनसे प्रभावित होने की संभावना नहीं है।

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