Проблема измерения N раз Время выполнения блока кода

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

  •  26-09-2019
  •  | 
  •  

Вопрос

РЕДАКТИРОВАТЬ: Я только что нашел свою проблему после написания этого долгая пост, объясняя каждую маленькую деталь ... Если кто-то может дать мне хороший ответ на то, что я делаю не так, и как я могу получить время исполнения в считанные секунды (используя поплавок с 5 десятичными периодами Или так), я отмечу это как принято. Подсказка: проблема была на том, как я интерпретировал страницу MACK_GETTTIME ().

Привет,

Допустим, у меня есть функция по имени myOperation Что мне нужно для измерения времени выполнения. Измерить его, я использую clock_gettime() Как это было рекомендовано здесь в одном из комментариев.

Мой учитель рекомендует нам измерить его N Таким образом, мы можем получить среднее, стандартное отклонение и медиана для окончательного доклада. Он также рекомендует нам выполнить myOperation M раз вместо одного. Если myOperation очень быстрая работа, измеряя его M раз позволяют нам получить чувство «реального времени», которое требуется; Причина, поскольку используемые часы, не могут иметь необходимую точность для измерения такой операции. Итак, исполнение myOperation только один раз или M Времена действительно зависит, если сама операция принимает достаточно долго, для точной точности, мы используем.

У меня проблемы с этим заниматься M время исполнения. Увеличение M уменьшается (много) конечное среднее значение. Что не имеет смысла для меня. Это похоже на это, в среднем вы берете от 3 до 5 секунд, чтобы путешествовать от пункта A до B. Но затем вы идете от A до B и обратно в 5 раз (что делает его в 10 раз, потому что B - B - это так же, как B к а) и вы измеряете это. Чем вы разделяете на 10, среднее значение, которое вы получаете, одинаково, что вы можете путешествовать от точки A до B, что составляет от 3 до 5 секунд.

Это то, что я хочу, чтобы мой код сделать, но это не работает. Если я продолжаю увеличивать количество раз, когда я иду от до B и обратно, среднее значение будет ниже и снизить каждый раз, это не имеет смысла для меня.

Достаточно теории, вот мой код:

#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. Отказ Общее время потребовалось 574133641Н, что было бы примерно 0,5с; Это невозможно, потребовалось пару минут, как я не мог смотреть на экран ждать и пошел что-то съесть.

Это было полезно?

Решение

Вам просто нужно изменить свой 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, и распечатки в соответствии с людьми:

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

Другие советы

Похоже, тип TimeClock имеет два поля, один в течение секунд и один для наносекунд. Не имеет смысла просто разделить поле наносец с количеством операций. Вам нужно разделить общее время.

Если вы используете систему 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);

Таким образом, вам не нужно иметь дело с двумя целыми числами, один с секундами и одним с микросекундами. Добавление и вычитание времени будут работать очевидно.

Я обычно использую функцию времени () для этого. Это показывает настенные часы времени, но это действительно то, что я забочусь в конце.

Один Gotcha с тестированием производительности - это операционная система может кэшировать операции, связанные с файловой системой. Таким образом, второй (а позже) пробеги могут быть намного быстрее, чем первый пробег. Важно, чтобы вы должны проверить майские операции и в среднем результат, чтобы получить доброе значение для результатов любых изменений, которые вы делаете. Там так много переменных, которые могут помочь вам отфильтровать шум.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top