C: использование clock() для измерения времени в многопоточных программах

Я всегда использовал clock(), чтобы измерить, сколько времени мое приложение взяло от начала до конца, как;

int main(int argc, char *argv[]) {
  const clock_t START = clock();

  // ...

  const double T_ELAPSED = (double)(clock() - START) / CLOCKS_PER_SEC;
}

Поскольку я начал использовать потоки POSIX, это, похоже, терпит неудачу. Похоже, часы() увеличиваются в N раз быстрее с N потоками. Поскольку я не знаю, сколько потоков будет выполняться одновременно, этот подход терпит неудачу. Итак, как я могу измерить, сколько времени прошло?

Ответ 1

clock() измерять время процессора, используемое вашим процессом, а не время настенных часов. Когда вы работаете одновременно с несколькими потоками, вы можете значительно быстрее прожечь процессорное время.

Если вы хотите узнать время выполнения настенных часов, вам необходимо использовать соответствующую функцию. Единственный в ANSI C - time(), который обычно имеет только 1 секунду разрешения.

Однако, как вы сказали, вы используете POSIX, это означает, что вы можете использовать clock_gettime(), определенный в time.h. Для этого лучше всего использовать часы CLOCK_MONOTONIC:

struct timespec start, finish;
double elapsed;

clock_gettime(CLOCK_MONOTONIC, &start);

/* ... */

clock_gettime(CLOCK_MONOTONIC, &finish);

elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;

(Обратите внимание, что я тщательно провел расчет elapsed, чтобы убедиться, что точность не теряется при очень коротких интервалах времени).

Если ваша ОС не предоставляет CLOCK_MONOTONIC (которую вы можете проверить во время выполнения с помощью sysconf(_SC_MONOTONIC_CLOCK)), вы можете использовать CLOCK_REALTIME как резервную копию, но обратите внимание, что последний имеет тот недостаток, что он будет генерировать неверные результаты, если системное время изменяется во время работы вашего процесса.

Ответ 2

Какое временное разрешение вам нужно? Вы можете использовать time() с time.h для второго разрешения. Если вам требуется более высокое разрешение, вы можете использовать что-то более специфичное для системы. См. Функция таймера для предоставления времени в nano секундах с использованием С++