Is clock_gettime() correctly implemented in MinGW GCC 8.2.0?

我们两清 提交于 2020-06-29 04:04:16

问题


By chance, I found out about the existence of the clock_gettime() function for Linux systems. Since I'm looking for a way to measure execution time of a function, I tried it in the MinGW gcc 8.2.0 version on a Windows 10 64-bit machine:

#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;
}

This code snippet compiles without warnings/errors, and there are no runtime failures (at least not written to stdout).

Output:

It takes 0 nanoseconds for 100,000 empty iterations.

Which I don't believe is true.

Can you spot the flaw?


One more thing:

According to the N1570 Committee draft (April 12, 2011) of the ISO/IEC 9899:201x, shouldn't timespec_get() take the role of clock_gettime() instead?


回答1:


That loop should get optimized out to nothing at all, so with a low resolution clock (resolution is not necessarily individual nanoseconds; it may advance in much larger units which clock_getres should be able to tell you) 0 is a plausible result. But you have a few other bugs in your code like mixing CLOCK_THREAD_CPUTIME_ID with CLOCK_PROCESS_CPUTIME_ID and not checking the return value of clock_gettime (it might be telling you these clocks aren't supported).




回答2:


First of all, your code is querying two different clocks (CLOCK_THREAD_CPUTIME_ID for tstart and CLOCK_PROCESS_CPUTIME_ID for tend), so it makes no sense to compare the two values. Secondly, you're only looking at the tv_nsec field of the struct timespec returned by clock_gettime(), and your difference might be wrong even if querying the same clock both times. Also, your compiler could be optimizing the empty for loop away, but that's impossible to say without looking at the generated binary, however I would find that unlikely unless you were compiling with -O1 or -O2 (see here for example, the loop is eliminated only with -O2).

Furthermore, Windows is not POSIX compliant at all, and MinGW can only emulate the behavior of clock_gettime() to some extent, so I wouldn't really trust it to return precise values. It seems to be okay for mingw-w64 looking at the source code, but I don't know if that's the version you're using. Even though a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second. You might want to check what clock_getres() says.

According to the N1570 Committee draft (April 12, 2011) of the ISO/IEC 9899:201x, shouldn't timespec_get() take the role of clock_gettime() instead?

The C standard does not say anything about which function should take the role of which other. The timespec_get() function definitely does not have the same semantics as clock_gettime(). The timespec_get() function only works on "calendar time" (which should be the same as CLOCK_REALTIME when using clock_gettime()).



来源:https://stackoverflow.com/questions/60020968/is-clock-gettime-correctly-implemented-in-mingw-gcc-8-2-0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!