كيفية قياس المعالجات متعددة النواة
-
04-10-2019 - |
سؤال
أبحث عن طرق لأداء العلامات الدقيقة على المعالجات متعددة النواة.
سياق:
في نفس الوقت تقريبًا ، قدمت معالجات سطح المكتب التنفيذ خارج الترتيب والتي جعلت الأداء صعبًا للتنبؤ بها ، وربما ، ربما ليسوا من قبيل الصدفة ، قدموا أيضًا تعليمات خاصة للحصول على توقيت دقيق للغاية. مثال على هذه التعليمات rdtsc
على x86 و rftb
على PowerPC. أعطت هذه الإرشادات توقيتًا أكثر دقة مما يمكن أن يسمح به مكالمة النظام ، سمح للمبرمجين بالقيام بالقلوب الصغيرة ، للأفضل أو للأسوأ.
على معالج أكثر حداثة مع العديد من النوى ، بعضها ينام بعض الوقت ، لا يتم مزامنة العدادات بين النوى. قيل لنا ذلك rdtsc
لم يعد آمنًا للاستخدام في القياس ، لكن لا بد لي من التغلب عندما تم شرح الحلول البديلة.
سؤال:
قد توفر بعض الأنظمة واستعادة عداد الأداء وتوفر مكالمة API لقراءة المبلغ المناسب. إذا كنت تعرف ما هي هذه المكالمة لأي نظام تشغيل ، فيرجى إخبارنا في إجابة.
قد تسمح بعض الأنظمة بإيقاف تشغيل النوى ، وترك تشغيل واحد فقط. أعرف أن Mac OS X Leopard يفعل عندما يتم تثبيت جزء التفضيل المناسب من أدوات المطورين. هل تعتقد أن هذا يجعل rdtsc
آمن للاستخدام مرة أخرى؟
المزيد من السياق:
يرجى افتراض أنني أعرف ما أفعله عند محاولة القيام بموجب صغير. إذا كنت ترى أنه إذا كان لا يمكن قياس مكاسب التحسين عن طريق توقيت التطبيق بأكمله ، فلا يستحق التحسين ، فأنا أتفق معك ، ولكن
لا يمكنني الوقت للتطبيق بأكمله حتى يتم الانتهاء من بنية البيانات البديلة ، والتي ستستغرق وقتًا طويلاً. في الواقع ، إذا لم تكن المرحلة الدقيقة واعدة ، فقد قررت التخلي عن التنفيذ الآن ؛
أحتاج إلى أرقام لتوفيرها في منشور لم يكن لدي أي سيطرة على الموعد النهائي.
المحلول
على OSX (الذراع ، Intel و PowerPC) ، تريد استخدامها mach_absolute_time( )
:
#include <mach/mach_time.h>
#include <stdint.h>
// Utility function for getting timings in nanoseconds.
double machTimeUnitsToNanoseconds(uint64_t mtu) {
static double mtusPerNanosecond = 0.0;
if (0.0 == mtusPerNanosecond) {
mach_timebase_info_data_t info;
if (mach_timebase_info(&info)) {
// Handle an error gracefully here, whatever that means to you.
// If you do get an error, something is seriously wrong, so
// I generally just report it and exit( ).
}
mtusPerNanosecond = (double)info.numer / info.denom;
}
return mtu * mtusPerNanosecond;
}
// In your code:
uint64_t startTime = mach_absolute_time( );
// Stuff that you want to time.
uint64_t endTime = mach_absolute_time( );
double elapsedNanoseconds = machTimeUnitsToNanoseconds(endTime - startTime);
لاحظ أنه ليست هناك حاجة إلى الحد من جوهر واحد لهذا الغرض. يعالج نظام التشغيل الإصلاح المطلوب وراء الكواليس mach_absolute_time( )
لإعطاء نتائج متوسطة في بيئة متعددة النواة (ومتعددة المقبس).
نصائح أخرى
تقوم النوى بإرجاع القيم المزامنة الصحيحة لـ "RTDSC". إذا كان لديك جهاز متعدد الجوانب ، فعليك إصلاح العملية على مأخذ توصيل واحد. ليست هذه هي المشكلة.
المشكلة الرئيسية هي أن المجدول يجعل البيانات غير موثوق بها. هناك بعض واجهة برمجة تطبيقات الأداء لـ Linux kernel> 2.6.31 لكنني لم أنظر إليها. يقوم Windows> Vista بعمل رائع هنا ، واستخدم QueryThreadCletime و QueryProcessCycletime.
لست متأكدًا من OSX ولكن AFAIK "Mach_absolute_time" لا يعدل الوقت المحدد.