ما يمكن أن يسبب عملية حتمية لتوليد أخطاء النقطة العائمة

StackOverflow https://stackoverflow.com/questions/968435

سؤال

بعد قراءة هذا بالفعل سؤال أنا معقول بشكل معقول أن عملية معينة تستخدم الحسابات النقطة العائمة مع نفس المدخلات (على نفس الأجهزة، التي تم تجميعها مع نفس التحويل البرمجي) يجب أن تكون حتمية. أنا أبحث في حالة حيث هذا ليس صحيحا ومحاولة تحديد ما كان قد تسبب في ذلك.

لقد قمت بتجميع ملف قابل للتنفيذ وأنا أطعمه نفس البيانات بالضبط، يعمل على جهاز واحد (غير متعدد المراحل) ولكني أحصل على أخطاء من حوالي 3.814697265625e-06 والتي بعد أن أصبحت googling الدقيق التي وجدتها في الواقع 1 / 4 ^ 9 = 1/2 ^ 18 = 1/262144. وهو قريب جدا من المستوى الدقيق لعدد نقطة عائمة 32 بت (حوالي 7 أرقام وفقا ل Wikipedia)

شكوكي هو أنه له علاقة بالتحسينات التي تم تطبيقها على التعليمات البرمجية. أنا أستخدم مترجم Intel C ++ وقام بتشغيل المضاربة العائمة بسرعة بدلا من آمنة أو صارمة. هل يمكن أن تجعل هذا عملية نقطة عائمة غير محددة؟ هل هناك تحسينات أخرى وغيرها التي يمكن أن تؤدي إلى هذا السلوك؟

تعديل: حسب اقتراح PAX، قمت بإعادة ترجمة التعليمات البرمجية مع تحول المضاربة العائمة إلى آمنة وأنا الآن الحصول على نتائج مستقرة. هذا يسمح لي بتوضيح هذا السؤال - ما الذي تفعله المضاربة العائمة بالفعل وكيف يمكن أن يؤدي ذلك إلى أن نفس الثنائي (أي مجموعة واحدة أو تشغيل متعددة) لتوليد نتائج مختلفة عند تطبيقها على نفس المدخلات بالضبط؟

ben أنا أرويج باستخدام Intel (R) C ++ 11.0.061 [IA-32] وأنا أركض على معالج Intel QuadCore.

هل كانت مفيدة؟

المحلول

في أي موقف تقريبا حيث يوجد وضع سريع ووضع آمن، ستجد مقاذاة من نوع ما. خلاف ذلك سوف يعمل كل شيء في وضع آمن سريع :-).

وإذا كنت تحصل على نتائج مختلفة بنفس المدخلات، فإن عمليةك هي ليس حتمية، بغض النظر عن مقدار تعتقد أنه (على الرغم من الأدلة التجريبية).

أود أن أقول تفسيرك هو الأكثر احتمالا. ضعه في الوضع الآمن ومعرفة ما إذا كان غير الحتمية يذهب بعيدا. سيخبرك بالتأكيد.

فيما إذا كانت هناك تحسينات أخرى، إذا كنت تجميعها على نفس الأجهزة مع نفس المترجم / رابط والنفس الخيارات لتلك الأدوات, ، يجب أن تولد رمز متطابق. لا أستطيع أن أرى أي احتمال آخر بخلاف الوضع السريع (أو تعفن بت في الذاكرة بسبب الأشعة الكونية، ولكن هذا غير مرجح للغاية).

متابعة التحديث الخاص بك:

إنتل لديه وثيقة هنا وهذا ما يفسر بعض الأشياء التي لا يسمح لها بالقيام بها في الوضع الآمن، بما في ذلك ولكن لا تقتصر على:

  • recectociation: (a+b)+c -> a+(b+c).
  • صفر قابلة للطي: x + 0 -> x, x * 0 -> 0.
  • مضاعفة متبادلة: a/b -> a*(1/b).

بينما تنص على أن هذه العمليات تجميع الوقت المحدد، فإن رقائق Intel مجدأة جميلة. يمكنهم إعادة طلب التعليمات لإبقاء خطوط الأنابيب ممتلئة في إعدادات وحدة المعالجة المركزية متعددة المعالجة المركزية، ما لم يحظر الكود على وجه التحديد مثل هذا السلوك، قد تتغير الأمور في وقت التشغيل (لا تجميع-وقت) للحفاظ على الأمور في سرعة كاملة.

يتم تغطية هذا (لفترة وجيزة) في الصفحة 15 من المستند المرتبط الذي يتحدث عن Vectorization ("المشكلة: نتائج مختلفة إعادة تشغيل نفس الثنائي على نفس البيانات على نفس المعالج").

ستكون نصيحتي هي أن تقرر ما إذا كنت بحاجة إلى نخر خام أو استنساخ إجمالي للنتائج ثم اختر الوضع بناء على ذلك.

نصائح أخرى

إذا تم توزز البرنامج، لأنه قد يكون من الجري على نواة رباعية، فقد تكون غير محتملة.

تخيل أن لديك 4 معالجات تضيف قيمة نقطة عائمة إلى نفس موقع الذاكرة. ثم قد تحصل

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

أو

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

أو أي من الأوامر الأخرى المحتملة.

هيك، قد تحصل حتى

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

إذا كان التحويل البرمجي جيد بما فيه الكفاية.

لسوء الحظ، فإن إضافة النقطة العائمة ليست متعة أو مشتركة. رقم الحساب الحقيقي هو، ولكن النقطة العائمة ليست، بسبب التقريب والفيضان ودمجها.

لهذا السبب، غالبا ما يكون حساب FP متوازي غير محدد. "في كثير من الأحيان"، لأن البرامج التي تبدو

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

ستكون غير حتمية، لأن مقدار الوقت الذي يستغرقه كل قد يختلف على نطاق واسع - لا يمكنك التنبؤ بأمر العمليات. (أسوأ إذا كانت المواضيع التفاعل.)

ولكن ليس دائما، لأن هناك أنماط من البرامج الموازية المحتملة.

بالطبع، ما هو العديد من الأشخاص الذين يهتمون بالحتمية يفعلون العمل في عدد صحيح أو نقطة ثابتة لتجنب المشكلة. أنا مغرم بشكل خاص من العوائق، 512، 1024، أو 2048 بت أن أرقام النقطة العائمة يمكن إضافتها إلى، دون تعاني من أخطاء التقريب.


بالنسبة لتطبيق واحد الخيوط: قد يعيد التحويل البرمجي رمز. مجموعات مختلفة قد تعطي إجابات مختلفة. لكن أي ثنائي معين يجب أن يكون حتميا.

ما لم ... أنت تعمل في لغة ديناميكية. الذي يؤدي التحسينات التي تم إعادة ترتيب حسابات FP، التي تختلف مع مرور الوقت.

أو ما لم ... تسديدة طويلة حقا: كان لدى Itanium بعض الميزات، مثل Alat، التي جعلت حتى غير محددة ترميز الخيوط. من غير المحتمل أن تتأثر هذه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top