مشكلة قياس N مرات وقت التنفيذ من كتلة التعليمات البرمجية

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

  •  26-09-2019
  •  | 
  •  

سؤال

تحرير: أنا فقط وجدت مشكلة بعد كتابة هذا الوقت بعد شرح كل التفاصيل الصغيرة...إذا كان شخص ما يمكن أن تعطيني إجابة جيدة على ما أفعله خطأ و كيف يمكنني الحصول على وقت التنفيذ في ثواني (باستخدام تطفو مع 5 أرقام عشرية أو نحو ذلك) ، سوف مارك أن يقبل.تلميح:المشكلة في كيف تفسر clock_getttime() صفحة.

مرحبا ،

دعونا نقول لدي وظيفة اسمه myOperation التي تحتاج إلى قياس وقت تنفيذ.لقياس ذلك, أنا باستخدام clock_gettime() كما كان يوصي هنا في أحد التعليقات.

أستاذي توصي لنا لقياس ذلك N مرات حتى نتمكن من الحصول على المتوسط الانحراف المعياري المتوسط في التقرير النهائي.كما توصي لنا لتنفيذ myOperation M مرات بدلا من واحد فقط.إذا myOperation سريع جدا في عملية القياس M مرات تسمح لنا للحصول على شعور من "الوقت الحقيقي" يلزم ؛ سبب الساعة المستخدمة قد لا يكون بالدقة اللازمة لقياس هذه العملية.لذا التنفيذ myOperation مرة واحدة فقط أو M مرات حقا يتوقف إذا كانت العملية نفسها تستغرق وقتا طويلا على مدار الساعة الدقة هي استخدام.

أواجه مشكلة في التعامل مع هذا M مرات التنفيذ.زيادة M النقصان (الكثير) المعدل النهائي القيمة.الذي لا معنى له بالنسبة لي.انها مثل هذا في المتوسط كنت تأخذ من 3 إلى 5 ثوان السفر من نقطة أ إلى ب.ولكن بعد ذلك تذهب من A إلى B إلى 5 مرات (مما يجعل من 10 مرات ، يؤدي إلى B هو نفسه كما كان من ب إلى أ) و يمكنك قياس ذلك.مما القسمة على 10 ، متوسط تحصل عليه هو من المفترض أن يكون نفس متوسط كنت تأخذ السفر من النقطة أ إلى النقطة ب ، الذي هو من 3 إلى 5 ثوان.

هذا هو ما أريد كود لفعل, لكنه لا يعمل.إذا كنت الحفاظ على زيادة عدد مرات أذهب من ألف إلى باء مرة أخرى ، متوسط سوف يكون أقل في كل مرة ، فإنه لا معنى له بالنسبة لي.

ما يكفي من الناحية النظرية ، رمز:

#include <stdio.h>
#include <time.h>

#define MEASUREMENTS 1
#define OPERATIONS   1

typedef struct timespec TimeClock;

TimeClock diffTimeClock(TimeClock start, TimeClock end) {
    TimeClock aux;

    if((end.tv_nsec - start.tv_nsec) < 0) {
        aux.tv_sec = end.tv_sec - start.tv_sec - 1;
        aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
    } else {
        aux.tv_sec = end.tv_sec - start.tv_sec;
        aux.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return aux;
}

int main(void) {
    TimeClock sTime, eTime, dTime;
    int i, j;

    for(i = 0; i < MEASUREMENTS; i++) {
        printf(" » MEASURE %02d\n", i+1);

        clock_gettime(CLOCK_REALTIME, &sTime);

        for(j = 0; j < OPERATIONS; j++) {
            myOperation();
        }

        clock_gettime(CLOCK_REALTIME, &eTime);

        dTime = diffTimeClock(sTime, eTime);

        printf("   - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
        printf("   - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
    }

    return 0;
}

ملاحظات: سبق diffTimeClock وظيفة من هذا بلوق وظيفة.استبدال بلدي العملية الحقيقية مع myOperation() لأنه لا يجعل من أي معنى ما وظائف حقيقية كما أود أن وظيفة طويلة كتل من التعليمات البرمجية ، يمكنك بسهولة رمز myOperation() مع كل ما كنت ترغب في ترجمة التعليمات البرمجية إذا كنت ترغب في ذلك.

كما ترون ، OPERATIONS = 1 والنتائج هي:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580

بالنسبة OPERATIONS = 100 النتائج:

 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297

بالنسبة OPERATIONS = 1000 النتائج:

 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834

بالنسبة OPERATIONS = 10000 النتائج:

 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413

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

هل يمكن أن تقول لي أن هذا في الواقع تعتمد على العملية نفسها ، فإن البيانات يتم قراءة و أن بعض البيانات قد تكون بالفعل في ذاكرة التخزين المؤقت و bla bla, ولكن لا أعتقد أن هذه هي المشكلة.في حالتي ، myOperation هو القراءة 5000 أسطر من النص من ملف CSV فصل القيم عن ; وإدراج تلك القيم إلى بنية البيانات.لكل التكرار انا تدمير بنية البيانات و تهيئة ذلك مرة أخرى.

الآن بعد أن أفكر في ذلك ، كما أن أعتقد أن هناك مشكلة قياس الوقت مع clock_gettime(), ربما لست في استخدام ذلك الحق.أعني نظرة على الماضي ، OPERATIONS = 10000.إجمالي الوقت كان 574133641ns التي ستكون تقريبا 0,5 s ؛ هذا مستحيل, استغرق الأمر بضع دقائق كما لم أستطع الوقوف و النظر في شاشة الانتظار وذهب إلى أكل شيء.

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

المحلول

تحتاج فقط إلى تغيير الخاص بك diffTimeClock() الدالة بإرجاع عدد الثواني الفرق ، double:

double diffTimeClock(TimeClock start, TimeClock end) {
    double diff;

    diff = (end.tv_nsec - start.tv_nsec) / 1E9;
    diff += (end.tv_sec - start.tv_sec);

    return diff;
}

و في روتين الرئيسي تغيير dTime إلى double, و printfs لتناسب:

printf("   - SEC (TOTAL): %f\n", dTime);
printf("   - SEC (OP): %f\n\n", dTime / OPERATIONS);

نصائح أخرى

يبدو TimeClock نوع حقلين واحد لمدة ثانية واحدة نانو ثانية.فإنه لا معنى أن مجرد تقسيم nanosec المجال مع عدد من العمليات.تحتاج إلى تقسيم الوقت الإجمالي.

إذا كنت تستخدم POSIX النظام حيث هناك gettimeofday() وظيفة يمكنك استخدام شيء من هذا القبيل للحصول على الوقت الحالي في ميكروثانية:

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}

السبب في هذا هو مفيد جدا هو أنه من أجل حساب مقدار الدالة أخذت عليك القيام به فقط:

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

لذلك لم يكن لديك للتعامل مع اثنين من الاعداد الصحيحه ، مع ثانية واحدة مع ميكروثانية.إضافة وطرح مرات في طريقة واضحة.

عموما أنا استخدم الدالة time() هذا.فإنه يدل على الجدار على مدار الساعة الوقت ، ولكن هذا حقا ما يهمني في نهاية المطاف.

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

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