الطريقة الأكثر فاعلية لضبط التسجيل على 1 أو (-1)
-
26-09-2019 - |
سؤال
أنا أتناول دورة تجميع الآن ، والرجل الذي يتحقق من مهامنا المنزلية هو مهووس بالمدرسة القديمة للغاية. على سبيل المثال ، يخصم 10 ٪ إذا رأى:
mov ax, 0
بدلاً من:
xor ax,ax
حتى لو تم استخدامه مرة واحدة فقط.
أنا لست مبتدئًا كاملًا في برمجة التجميع ، لكنني لست خبيرًا في التحسين ، لذلك أحتاج إلى مساعدتكم في شيء ما (قد يكون سؤالًا غبيًا للغاية ولكن سأطرحه على أي حال): إذا كنت بحاجة إلى تعيين قيمة التسجيل على 1 أو (-1) هل من الأفضل استخدام:
mov ax, 1
أو افعل شيئًا مثل:
xor ax,ax
inc ax
أنا حقًا بحاجة إلى درجة جيدة ، لذلك أحاول الحصول عليها قدر الإمكان. (أحتاج إلى تحسين كل من الوقت وحجم الرمز)
المحلول
جوجل السريع ل 8086 instructions timings size
يتحول http://8086.tk/ التي يبدو أن لديها كل التوقيت والأحجام لمجموعات التعليمات 8086 (والمزيد).
لا شك أنه يمكنك العثور على Intel DoCo الرسمي على الويب بمعلومات مماثلة.
لسؤالك المحدد:
xor ax,ax
inc ax
يأخذ 3+3 = 6 دورات على مدار الساعة و 2+1 = 3 بايت أثناء
mov ax,1
يأخذ 4 دورات على مدار الساعة و 3 بايت.
لذلك فإن الأخير أفضل في هذه الحالة.
لكن عليك التحدث إلى معهدك التعليمي حول هذا الرجل. 10 ٪ لشيء بسيط مثل هذا الاعتقاد المتسولين.
يجب أن تسأل عما يجب القيام به في الحالة التي يكون لديك فيها احتمالان ، أحدهما أسرع وواحد أقصر.
بعد ذلك ، بمجرد أن يعترفوا بأن هناك طرقًا مختلفة للترميز اعتمادًا على ما تحاول تحقيق دورة أو بايت هنا أو هناك*أ.
التحسين هو شيء تقوم به عمومًا إذا كان لديك مشكلة في الأداء ، وبعد أن يكون جزء من الكود في حالة شبه كاملة-إنه جهد يضيع دائمًا عندما لا يزال الرمز يخضع لاحتمال تغيير غير مهم.
لما يستحق، sub ax,ax
يبدو أنه على قدم المساواة مع xor ax,ax
من حيث دورات الساعة والبايت ، لذلك ربما يمكنك رمي ذلك في المزيج في المرة القادمة لتسبب المزيد من الأعمال.
*أ) لا ، لا ، ولكن من الممتع التنفيس من حين لآخر :-)
نصائح أخرى
أنت أفضل حالًا
فأس mov ، 1
في 8086. إذا كنت تتتبع محتويات السجل ، فيمكنك القيام بعمل أفضل إذا كنت تعرف ذلك ، على سبيل المثال ، BX بالفعل 1 في ذلك:
الفأس MOV ، BX
أو إذا كنت تعلم أن آه هو 0:
mov al ، 1
إلخ.
اعتمادًا على ظروفك ، قد تكون قادرًا على الابتعاد عن ...
sbb ax, ax
ستكون النتيجة إما 0 إذا لم يتم تعيين علامة الحمل أو -1 إذا تم تعيين علامة الحمل.
ومع ذلك ، إذا كان المثال أعلاه لا ينطبق على موقفك ، فإنني أوصي
xor ax, ax
inc ax
طريقة. يجب أن ترضي أستاذك للحجم. ومع ذلك ، إذا قام المعالج الخاص بك بتأييد أي إبطال أنابيب ، أتوقع أن يكون هناك بعض التأخير الشبيه بالاقتران بين التعليمات (قد أكون مخطئًا في ذلك). في حالة وجود مثل هذا الاقتران ، يمكن تحسين السرعة قليلاً عن طريق إعادة ترتيب التعليمات الخاصة بك قليلاً للحصول على تعليمات أخرى بينهما (واحدة لا تستخدم AX).
أتمنى أن يساعدك هذا.
سأستخدم mov [e]ax, 1
تحت أي ظرف من الظروف. ترميزها لم يعد من المتسللين xor
التسلسل ، وأنا متأكد من أنه أسرع في أي مكان. 8086 هو مجرد غريب بما يكفي ليكون الاستثناء ، وبما أن هذا الشيء بطيء للغاية ، فإن التحسين الجزئي مثل هذا سيحدث فرقًا كبيرًا. ولكن في أي مكان آخر: سيكون تنفيذ تعليمات "سهلة" دائمًا أبطأ من تنفيذ 1 ، خاصة إذا كنت تفكر في مخاطر البيانات وخطوط الأنابيب الطويلة. تحاول قراءة سجل في التعليمات التالية بعد تعديله ، لذلك ما لم تتمكن وحدة المعالجة المركزية الخاصة بك من تجاوز النتيجة من المرحلة n من خط الأنابيب (حيث xor
يتم تنفيذها) لتنظيم N-1 (حيث تحاول شركة INC حمل السجل ، لا تمانع في إضافة 1 إلى قيمته) ، سيكون لديك أكشاك.
أشياء أخرى يجب مراعاتها: تعليمات الجلب النطاق الترددي (Moot for 16 بت ، كلاهما 3 بايت) ؛ mov
يتجنب تغيير الأعلام (من المرجح أن تكون مفيدة من إجبارها جميعًا على الصفر) ؛ اعتمادًا على القيم التي قد تكون عليها السجلات الأخرى ، ربما يمكنك القيام بها lea ax,[bx+1]
(أيضًا 3 بايت ، حتى في رمز 32 بت ، لا يوجد تأثير على الأعلام) ؛ كما قال آخرون ، sbb ax,ax
يمكن أن تعمل أيضًا في الظروف - إنه أقصر أيضًا في 2 بايت.
عندما تواجه هذه الأنواع من التحسينات الصغيرة يجب عليك حقًا معيار البدائل بدلاً من الاعتماد بشكل أعمى حتى على أدلة المعالج.
PS الواجبات المنزلية الجديدة: هو xor bx,bx
أي أسرع من xor bx,cx
(على أي معالج)؟