Ответ 1
Посмотрите clock_gettime
, который обеспечивает доступ к таймерам с высоким разрешением.
Я ищу быстрый способ получить прошедшее время между двумя вызовами функции в C.
Я рассматривал использование jiffies, но они недоступны в userland. Итак, следует ли использовать getimeofday() или есть самый быстрый способ сделать это.
Меня интересует только ускоренное время между двумя вызовами, которое можно использовать в тестовом инструменте.
Посмотрите clock_gettime
, который обеспечивает доступ к таймерам с высоким разрешением.
Я получаю процессорное время через clock()
от time.h
. Чтобы получить полезные значения, преобразуйте их в миллисекунды через CLOCKS_PER_SEC
:
clock_t start = clock();
// [...]
clock_t end = clock();
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;
Да, gettimeofday() будет достаточным, если вы захотите найти фактическое истекшее. Если вам нужно найти процессорное время, вы можете использовать clock(). Во многих случаях оба подхода дали бы аналогичный результат (если в коде нет сна или какого-то ожидания). Пример clock() можно найти здесь:
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_19.html
Если вы работаете с архитектурой x86/x64 и работаете на одном процессоре, вы можете рассмотреть возможность считывания счетчика времени для процессора, чтобы получить счетчик циклов. Wikipedia больше информации. Обратите внимание, что этот подход менее полезен, если ваше приложение работает на нескольких процессорах, поскольку каждый процессор будет иметь свой собственный TSC. Также будьте осторожны с частотным масштабированием, если вы решите, что хотите преобразовать циклы → единицы времени.
Если ваше ядро поддерживает gettimeofday()
как vsyscall (виртуальный системный вызов), то использование этого будет быстрее, чем вызов обычного системного вызова, например clock()
. См. презентация Andrea Arcangeli для получения некоторой информации о работе vsyscalls.
Немного позднего добавления, однако доступность времени, доступная на любом Linux/Unix, может быть более легким способом достижения желаемого. Вот 2 примера
time ls -l stuff*
ls: stuff*: No such file or directory
0.01s real 0.00s user 0.00s system
time -c run_script.csh`
...
real 1m22.38s
user 0m14.67s
sys 0m1.06s
Следующие работы для меня на CentOS 6:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if ! defined(_POSIX_C_SOURCE)
# error "_POSIX_C_SOURCE undefined"
#endif
#if _POSIX_C_SOURCE < 199309L
# error "_POSIX_C_SOURCE < 199309L"
#endif
int main(int, char**){
struct timespec start, stop;
struct timespec stop;
if(clock_gettime(CLOCK_MONOTONIC, &start )) goto err_out;
if(clock_gettime(CLOCK_MONOTONIC, &stop )) goto err_out;
printf("start == {tv_sec: %d, tv_nsec: %d}\n", start.tv_sec, start.tv_nsec);
printf("stop == {tv_sec: %d, tv_nsec: %d}\n", stop.tv_sec, stop.tv_nsec );
printf("stop.tv_nsec - start.tv_nsec == %d\n", stop.tv_nsec - start.tv_nsec);
return EXIT_SUCCESS;
err_out:
perror("clock_gettime");
return EXIT_FAILURE ;
}
... хотя для этого требуется librt
:
$ make dur
cc dur.c -o dur
/tmp/cc1yF58x.o: In function `main':
dur.c:(.text+0x1c): undefined reference to `clock_gettime'
dur.c:(.text+0x4e): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [dur] Error 1
$ LDFLAGS="-lrt" make dur
cc -lrt dur.c -o dur
$ ./dur
start == {tv_sec: 206247, tv_nsec: 411717209}
stop == {tv_sec: 206247, tv_nsec: 411759791}
stop.tv_nsec - start.tv_nsec == 42582