Правильно ли реализована функция clock_gettime () в MinGW G CC 8.2.0? - PullRequest
0 голосов
/ 01 февраля 2020

Случайно я узнал о существовании функции clock_gettime() для систем Linux. Поскольку я искал способ измерения времени выполнения функции, я попробовал его в версии MinGW g cc 8.2.0 на 64-битной машине Windows 10:

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

int main() {
    struct timespec tstart, tend;
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tstart);
    for (int i = 0; i < 100000; ++i);
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tend);
    printf("It takes %li nanoseconds for 100,000 empty iterations.\n", tend.tv_nsec - tstart.tv_nsec);
    return 0;
}

Этот фрагмент кода компилируется без предупреждений / ошибок, и нет сбоев во время выполнения (по крайней мере, не записанных в стандартный вывод).

Вывод:

It takes 0 nanoseconds for 100,000 empty iterations.

Что я не верю, что это правда.

Можете ли вы заметить недостаток?


Еще одна вещь:

Согласно проекту N1570 Комитета (12 апреля 2011 г.) ISO / IEC 9899: 201x, разве timespec_get() не должен взять на себя роль clock_gettime() вместо этого?

Ответы [ 2 ]

2 голосов
/ 02 февраля 2020

То, что l oop вообще должно быть оптимизировано до нуля, так что с часами низкого разрешения (разрешение не обязательно должно быть индивидуальными наносекундами; оно может увеличиваться в гораздо больших единицах, которые clock_getres должен быть в состоянии сообщить вам) 0 это правдоподобный результат. Но у вас есть несколько других ошибок в вашем коде, таких как смешивание CLOCK_THREAD_CPUTIME_ID с CLOCK_PROCESS_CPUTIME_ID и не проверка возвращаемого значения clock_gettime (возможно, это говорит о том, что эти часы не поддерживаются).

1 голос
/ 02 февраля 2020

Прежде всего, ваш код запрашивает два разных тактовых сигнала (CLOCK_THREAD_CPUTIME_ID для tstart и CLOCK_PROCESS_CPUTIME_ID для tend), поэтому нет смысла сравнивать эти два значения. Во-вторых, вы смотрите только на поле tv_nsec struct timespec, возвращаемое clock_gettime(), и ваша разница может быть неправильной, даже если запрашивать одни и те же часы оба раза. Кроме того, ваш компилятор может оптимизировать пустой for l oop, но это невозможно сказать, не глядя на сгенерированный двоичный файл, однако я считаю, что это маловероятно, если вы не компилировали с -O1 или -O2 (см. здесь например, l oop исключается только с -O2).

Кроме того, Windows вообще не совместим с POSIX, а MinGW может эмулировать только поведение clock_gettime() до некоторой степени, поэтому я бы не стал доверять возвращению точных значений. Кажется, это нормально для mingw-w64 , который просматривает исходный код , но я не знаю, какую версию вы используете. Даже если объект struct timespec описывает времена с наносекундным разрешением, доступное разрешение зависит от системы и может даже превышать 1 секунду. Возможно, вы захотите проверить, что говорит clock_getres().

Согласно проекту комитета N1570 (12 апреля 2011 г.) ISO / IEC 9899: 201x, не должен ли timespec_get() взять на себя роль clock_gettime() вместо этого?

Стандарт C не говорит что-либо о том, какая функция должна взять на себя роль какой Другой. Функция timespec_get() определенно не имеет ту же семантику, что и clock_gettime(). Функция timespec_get() работает только по «календарному времени» (которое должно совпадать с CLOCK_REALTIME при использовании clock_gettime()).

...