لماذا المزيد من تعليمات تجميع بنتيوم يستغرق وقتا أقل؟
سؤال
فيما يلي مقطع من قائمة بتسلسلات تجميع Pentium. لدينا حلقة خارجية تحاول الوقت تسلسلنا وتقوم بجدول مكالمة للوصول إلى هذه الروتين. لذلك، يتم إجراء المكالمة الخارجية من نفس الموقع في كل مرة. تختلف التسلسلان في أن أول واحد لديه تعليم أقل من الثانية.
النتائج التي نحصل عليها على اثنين من آلات إنتل مختلفة جدا.
تخبر تعليمات CPUID الأسرة والنموذج والتطوير.
الآلة 1: الأسرة 6، نموذج 15 خطوة 11. CPUZ تقارير "Intel Core 2 Duo E6750"
التعليمات تنفذ عند إحصائيا بنفس السرعة.
الآلة 2: الأسرة 15، نموذج 3، خطوة 3. تقارير CPUZ "Intel Pentium 4"
يستغرق التسلسل الأول حوالي 8٪ أطول من التسلسل الثاني.
نحن ببساطة لا يمكن أن تفسر الزيادة في الوقت المناسب. لا ينبغي أن يكون هناك أي أخلاف تخفيف العلم، والتنبؤ بالفروع، وتسجيل مشاكل الاستخدام، وما إلى ذلك على الأقل لا يمكننا أن نقول.
هل لدى أي شخص فكرة لماذا تستغرق التسلسل الأول وقتا أطول للتنفيذ على جهاز واحد؟
تحرير: إضافة "XOR PTR EREG، 0" إلى التسلسل الأول يجعل توقيت تتطابق مع المرتبة الثانية على بنتيوم 4. فضولي.
التسلسل الأول:
00000040 ALUSHIFT_AND_C_V_E LABEL NEAR
00000040 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000048 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000050 23 C2 AND EAX, EDX ; AX = L&R (result)
00000052 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
00000057 C3 RET ; Return
التسلسل الثاني:
00000060 ALUSHIFT_AND_C_V_NE LABEL NEAR
00000060 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000068 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000070 23 C2 AND EAX, EDX ; AX = L&R (result)
00000072 80 35 00000000 E XOR BYTE PTR ereg, 1 ; E = ~E
01
00000079 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
0000007E C3 RET ; Return
المحلول
بعد Pentium I أو II، معظم التحسينات التي يؤديها المحول البرمجي، لم تكن كذلك كما من الضروري. سوف تحلل الرقاقة هذه التعليمات في مايكرو OPS ثم تحسين لك. يمكن أن يكون T فروق التنبؤ الفرعي بين الرقائق أو حقيقة أن XOR + RET مكلفة تماما مثل Ret عادي. أنا لست على دراية نماذج Pentiums التي تنظر إليها أعلاه قولها. احتمال آخر هو أنه يمكن أن يكون أيضا مشكلة مخزئة التخزين المؤقت أو فرق الأجهزة.
قد يكون هناك شيء في مستندات Intel أو قد لا يحدث.
بغض النظر. يعرف مبردون الجمعيون ذوي الخبرة أن الحقيقة الوحيدة تتحقق عن طريق الاختبار، وهو ما تفعله.
نصائح أخرى
اتضح أن هناك بعض التفاعل الغريب مع حيث يوجد الكود الذي يسبب الزيادة. على الرغم من أن كل شيء يتماشى مخبأ، فإن تحويل كتل الكود تسبب في الزيادة في الوقت المناسب على Pentium-4
شكرا لجميع الذين أخذوا الوقت للتحقيق في هذا أو إلقاء نظرة عليه.
يمكنك إضافة نسخة واحدة، اثنان، إلخ، أمام هذا الرمز (وتغيير أي شيء آخر) لتحريك حيث هذه الأراضي في ذاكرة التخزين المؤقت لمعرفة ما إذا كانت هناك تأثيرات ذاكرة التخزين المؤقت (أو مجرد إيقاف تشغيل ذاكرة التخزين المؤقت). تحذير على الرغم من أن NOP الإضافي يمكن أن يغير التعليمات في مكان آخر غير قادر على الوصول إلى شيء ما باستخدام عنوان الكمبيوتر الشخصي، مما يؤدي إلى مزيد من البايتات المتعلقة بالتعليمات التي تسبب كل من التعليمات البرمجية قيد الاختبار لتحريك أكثر من الرغبة بالإضافة إلى رد فعل سلسلة تعليمات موجهة نسبيا أخرى للتغيير.
حتى إذا كنت تلعب لعبة ذاكرة التخزين المؤقت طبيعة الوحش هنا هو السحر داخل الشريحة التي تأخذ مجرى واحد من التعليمات وتقسيمها من بين وحدات التنفيذ.
القرص والاختبار هو ما يحصل عليه حقا في النهاية حتى لو كنت لا تفهم السبب. على الرغم من أنه بمجرد نقل هذا الرمز إلى رقاقة أكبر سنا أو رقاقة أحدث أو اللوحة الأم المختلفة أو نفس عائلة الرقاقة، إلا أن خطوة خطوة مختلفة يمكن أن تقوم بتشغيلك.
قبل بضعة أشهر، كان لدي شيء مماثل يحدث لي. يحتوي مشروعي على مفتاح التبديل لتمكين استخدام __thread
لمتغيرات الخيط المحلي. بدونها، سوف تستخدم pthread_getspecific
ويحب. هذا الأخير يفعل كل شيء بقدر __thread
الإصدار بالإضافة إلى وظيفة الدالة بالإضافة إلى بعض الإرشادات الإضافية لإعداد الوسائط وحفظ السجلات وما إلى ذلك. ومن المثير للاهتمام، أن النسخة الأكثر شاقة كانت أسرع باستمرار. فقط على بنتيوم 4، رغم ذلك. جميع رقائق أخرى تصرفت سلافية.