Почему интервалы gettimeofday () иногда бывают отрицательными? - PullRequest
5 голосов
/ 06 мая 2010

У меня есть экспериментальная библиотека, производительность которой я пытаюсь измерить. Для этого я написал следующее:

struct timeval begin;
gettimeofday(&begin, NULL);
{
    // Experiment!
}
struct timeval end;
gettimeofday(&end, NULL);

// Print the time it took!
std::cout << "Time: " << 100000 * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) << std::endl;

Иногда мои результаты включают отрицательные моменты времени, некоторые из которых бессмысленны. Например:

Time: 226762
Time: 220222
Time: 210883
Time: -688976

Что происходит?

Ответы [ 5 ]

7 голосов
/ 06 мая 2010

У вас есть опечатка.Исправленная последняя строка (обратите внимание на число 0):

std::cout << "Time: " << 1000000 * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) << std::endl;

Кстати, timersub - это встроенный метод для получения разницы между двумя временными интервалами.

3 голосов
/ 06 мая 2010

Библиотеки реального времени posix лучше подходят для измерения интервалов высокой точности.Вы действительно не хотите знать текущее время.Вы просто хотите знать, сколько времени прошло между двумя точками.Вот для чего нужны монотонные часы.

struct timespec begin;
clock_gettime( CLOCK_MONOTONIC, &begin );
{
    // Experiment!
}
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &end );

// Print the time it took!
std::cout << "Time: " << double(end.tv_sec - begin.tv_sec) + (end.tv_nsec - begin.tv_nsec)/1000000000.0 << std::endl;

При ссылке необходимо добавить -lrt.

Использование монотонных часов имеет ряд преимуществ.Он часто использует аппаратные таймеры (Гц кристалл или что-то в этом роде), поэтому это часто более быстрый вызов, чем gettimeofday().Также гарантируется, что монотонные таймеры никогда не пойдут назад, даже если ntpd или пользователь тратят время на системное время.

3 голосов
/ 06 мая 2010

std :: cout << "Время:" << 100000 * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) << std :: endl; </p>

Как уже отмечалось, в секунду 1000000 пользователей, а не 100000.

В более общем случае вам может потребоваться учитывать нестабильность синхронизации на компьютерах. Такие процессы, как ntpd, могут изменять часы, что приводит к неправильному времени дельты. Возможно, вас заинтересуют такие возможности POSIX, как timer_create.

2 голосов
/ 18 июля 2014

Вы позаботились об отрицательном значении, но оно все еще не правильно. Разница между миллисекундными переменными ошибочна, скажем, у нас есть начальное и конечное время как 1.100 и 2.051 с. По принятому ответу это будет истекшее время 1,049 с, что неверно.

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

if(end.tv_sec==begin.tv_sec)
printf("Total Time =%ldus\n",(end.tv_usec-begin.tv_usec));
else
printf("Total Time =%ldus\n",(end.tv_sec-begin.tv_sec-1)*1000000+(1000000-begin.tv_usec)+end.tv_usec);
0 голосов
/ 06 мая 2010

сделать

$ time ./proxy-application

в следующий раз

...