سؤال

أنا أتناول دورة تجميع الآن ، والرجل الذي يتحقق من مهامنا المنزلية هو مهووس بالمدرسة القديمة للغاية. على سبيل المثال ، يخصم 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 (على أي معالج)؟

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