النقطة العائمة مقابل النقطة الثابتة: ما هي إيجابيات/سلبيات؟

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

سؤال

يمثل نوع النقطة العائمة رقمًا عن طريق تخزين أرقامه المهمة وبرواكها بشكل منفصل على كلمات ثنائية منفصلة بحيث يناسب 16 أو 32 أو 64 أو 128 بت.

يخزن نوع النقطة الثابتة أرقام بكلمتين ، واحدة تمثل الجزء الأيمن ، وجينًا يمثل الجزء الذي يتجاوز الراديكس ، في الأسس السلبية ، 2^-1 ، 2^-2 ، 2^-3 ، إلخ.

تعويم أفضل لأن لديهم نطاقًا أوسع بمعنى الأسس ، ولكن ليس إذا أراد المرء تخزين الرقم بدقة أكبر لنطاق معين ، على سبيل المثال فقط باستخدام عدد صحيح من -16 إلى 16 ، وبالتالي استخدام المزيد من البتات لمكافحة الأرقام بعد الراديكس .

من حيث العروض ، أي واحد لديه أفضل أداء ، أو هل هناك حالات يكون فيها بعضها أسرع من الآخر؟

في برمجة ألعاب الفيديو ، هل يستخدم الجميع نقطة عائمة لأن FPU يجعلها أسرع ، أو لأن انخفاض الأداء ضئيل ، أم أنهم يصنعون نوعًا ثابتًا خاصًا به؟

لماذا لا يوجد أي نوع ثابت في C/C ++؟

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

المحلول

يغطي هذا التعريف مجموعة فرعية محدودة للغاية من تطبيقات النقاط الثابتة.

سيكون من الصواب القول أنه في النقطة الثابتة فقط يتم تخزين mantissa ويكون الأساس محددًا ثابتًا. لا يوجد أي شرط أن تسقط النقطة الثنائية داخل مانتيسا ، وبالتأكيد لا يوجد أي شرط أن تقع على حدود كلمة. على سبيل المثال ، كل ما يلي "نقطة ثابتة":

  • 64 بت mantissa ، مقاس 2-32 (هذا يناسب التعريف المدرج في السؤال)
  • 64 بت mantissa ، مقاس 2-33 (الآن لا يمكن فصل الأجزاء الصحيح والكسر بحدود الثماني)
  • 32 بت مانتيسا ، مقاس 24 (الآن لا يوجد جزء كسري)
  • 32 بت مانتيسا ، مقاس 2-40 (الآن لا يوجد جزء عدد صحيح)

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

بالنسبة لمطالبتك بأن C ++ ليس لديه نوع نقطة ثابتة ، فأنا لا أتفق. جميع أنواع عدد صحيح في C ++ هي أنواع النقاط الثابتة. غالبًا ما يُفترض أن يكون الأسس صفراً ، لكن هذا غير مطلوب ولدي الكثير من رمز DSP النقطة الثابتة التي تم تنفيذها في C ++ بهذه الطريقة.

نصائح أخرى

على مستوى التعليمات البرمجية ، فإن الحساب الثابت هو ببساطة حساب صحيح مع قاسم ضمني.

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

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

توفر بعض الهياكل تطبيقات الأجهزة لبعض وظائف الرياضيات ، مثل sin, cos, atan, sqrt, ، لأنواع النقطة العائمة فقط. بعض الهياكل لا توفر أي تنفيذ الأجهزة على الإطلاق. في كلتا الحالتين ، قد توفر مكتبات برامج الرياضيات المتخصصة تلك الوظائف باستخدام حساب عدد صحيح أو نقطة ثابتة فقط. في كثير من الأحيان ، ستوفر هذه المكتبات مستوى متعددًا من الدقة ، على سبيل المثال ، الإجابات التي لا تصل إلا إلى نوتات N-Bits من الدقة ، والتي هي أقل من الدقة الكاملة للتمثيل. قد تكون الإصدارات المحدودة الدقة أسرع من الإصدار الأعلى.

تستخدم النقطة الثابتة على نطاق واسع في DSP والأنظمة المضمنة حيث لا يوجد في كثير من الأحيان معالج الهدف FPU ، ويمكن تنفيذ نقطة ثابتة بشكل معقول باستخدام عدد صحيح ALU.

من حيث الأداء ، فإن هذا هو الحال لتختلف اعتمادًا على الهندسة المعمارية والتطبيق المستهدفين. من الواضح أنه إذا لم يكن هناك FPU ، فإن النقطة الثابتة ستكون أسرع بكثير. عندما يكون لديك FPU ، فسوف يعتمد على التطبيق أيضًا. على سبيل المثال ، سيكون أداء بعض الوظائف مثل SQRT () أو LOG () أسرع بكثير عند دعمه مباشرة في مجموعة التعليمات بدلاً من ذلك خوارزميات تم تنفيذها.

لا يوجد نوع من نقطة ثابتة مدمجة في C أو C ++ أتخيلها لأنها (أو على الأقل C) كانت متصورة كلغات على مستوى الأنظمة ، والنقطة الثابتة الحاجة محددة إلى حد ما ، وربما أيضًا لأن معالج الغرض العام هناك عادة لا يوجد دعم للأجهزة مباشرة للنقطة الثابتة.

في C ++ تحديد فئة نوع بيانات النقطة الثابتة مع عمليات تحميل مناسبة للمشغل ووظائف الرياضيات المرتبطة بها يمكن أن تتغلب بسهولة على هذا الاختصار. ومع ذلك ، هناك حلول جيدة وسيئة لهذه المشكلة. أ جيد يمكن العثور على مثال هنا: http://www.drdobbs.com/cpp/207000448. رابط الرمز في هذه المقالة مكسور ، لكنني تتبعته ftp://66.77.27.238/sourcecode/ddj/2008/0804.zip

يعتمد الاختلاف بين النقطة العائمة والرياضيات الصحيح على وحدة المعالجة المركزية التي تفكر فيها. على رقائق Intel ، فإن الفرق ليس كبيرًا في حدود الساعة. لا تزال الرياضيات الداخلية أسرع لأن هناك عدد صحيح متعدد يمكن أن يعمل بالتوازي. المترجمين ذكي أيضًا لاستخدام تعليمات حساب Adress الخاصة لتحسين إضافة/مضاعفة في تعليمات واحدة. يعتبر التحويل كعملية أيضًا ، لذا فقط اختر النوع والتمسك به.

في C ++ يمكنك إنشاء نوعك الخاص للرياضيات النقطة الثابتة. يمكنك فقط تحديد بنية مع int واحدة وتجاوز الحمولة الزائدة المناسبة ، وجعلها تفعل ما يفعلون عادة بالإضافة إلى تحول لوضع الفاصلة إلى الوضع الصحيح.

يجب أن تكون حذراً عند مناقشة "الدقة" في هذا السياق.

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

اعتمادًا أيضًا على الطريقة التي تقسم بها رقم النقطة الثابتة ، قد تكون قيمة النقطة العائمة قادرة على تمثيلها الأصغر الأرقام التي تعني أنها لديها تمثيل أكثر دقة لـ "Tiny لكن غير صفري".

وهلم جرا.

لا تستخدم Float في الألعاب لأنها أسرع أو أبطأ تستخدمها لأنه من الأسهل تنفيذ الخوارزميات في النقطة العائمة من النقطة الثابتة. أنت تفترض أن السبب يتعلق بسرعة الحوسبة وهذا ليس هو السبب ، فإنه يتعلق بسهولة البرمجة.

على سبيل المثال ، يمكنك تحديد عرض الشاشة/منفذ العرض من 0.0 إلى 1.0 ، ارتفاع الشاشة 0.0 إلى 1.0. عمق الكلمة 0.0 إلى 1.0. وهلم جرا. Matrix Math ، إلخ ، تجعل الأمور سهلة التنفيذ. قم بكل ما يصل إلى النقطة التي تحتاج فيها إلى حساب وحدات البكسل الحقيقية على حجم شاشة حقيقي ، على سبيل المثال 800 × 400. قم بإظهار الشعاع من العين إلى النقطة الموجودة على الكائن في العالم وحساب حيث يخترق الشاشة ، باستخدام 0 إلى 1 الرياضيات ، ثم اضرب x في 800 ، و y مرات 400 ووضع البكسل.

النقطة العائمة لا تخزن الأسس و mantissa بشكل منفصل و Mantissa هو رقم أبله ، ما تبقى بعد الأسس والتوقيع ، مثل 23 بت ، وليس 16 أو 32 أو 64 بت.

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

إحدى المشكلات التي لم يتم تغطيتها هي أن الإجابات هي استهلاك الطاقة. على الرغم من أن ذلك يعتمد إلى حد كبير على بنية الأجهزة المحددة ، إلا أن FPU تستهلك طاقة أكثر بكثير من ALU في وحدة المعالجة المركزية ، وبالتالي إذا كنت تستهدف تطبيقات الهاتف المحمول حيث يكون استهلاك الطاقة مهمًا ، فهذا يستحق النظر في انحراف النقطة الثابتة للخوارزمية.

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

الايجابيات والسلبيات تأتي إلى السرعة والموارد. على منصات 32 بت و 64 بت الحديثة ، لا توجد حاجة حقًا لاستخدام نقطة ثابتة. تأتي معظم الأنظمة مع FPUs التي يتم توصيلها بقوة لتوصيلها لعمليات النقطة الثابتة. علاوة على ذلك ، فإن معظم جوادات وحدة المعالجة المركزية الحديثة تأتي مع عمليات مثل مجموعة SIMD التي تساعد على تحسين الأساليب القائمة على المتجهات عبر التفتيت والتشويش. لذلك النقطة الثابتة تأتي فقط مع الجانب السلبي.

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

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