8000 Restore ability to use clock_gettime() on posix systems by Cyan4973 · Pull Request #3168 · facebook/zstd · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Restore ability to use clock_gettime() on posix systems #3168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

Cyan4973
Copy link
Contributor

When timespec_get() was unavailable,
timefn unit would fall back to clock_t,
which is unfortunately not good enough to measure speed in multi-threading scenarios.

@jbeich proposes a patch which re-enable clock_gettime() as an alternative for posix systems.
(I can't remember why it was removed...)
This extends the nb of platforms that can use a timer function compatible with multi-threading scenarios.

@Cyan4973
Copy link
Contributor Author

arf ...

If the defined operator appears as a result of a macro expansion, the C standard says the behavior is undefined

source

@Cyan4973
Copy link
Contributor Author
Cyan4973 commented Jun 20, 2022

Still this issue :

../programs/timefn.h:22: error: "_POSIX_C_SOURCE" redefined [-Werror]
   22 | #define _POSIX_C_SOURCE 200809L /* clock_gettime */

Not sure if it's really possible to force a specific posix level.
This happens in the c99 test, which might force a specific level of its own.

jbeich and others added 3 commits June 19, 2022 17:47
- cmake/meson pass -std=gnu99 which hits clock() fallback
- clock() fallback skews multi-threading benchmarks
- TIME_UTC (C11) is similar to CLOCK_REALTIME (POSIX)
- GNU may hide CLOCK_REALTIME in -std=c99 (__STRICT_ANSI__)
- Switch to CLOCK_MONOTONIC like before 36d2dfd
which restore clock_gettime() as a way to get a usable timer for posix systems.
Original PR by @jbeich
@Cyan4973
Copy link
Contributor Author
Cyan4973 commented Jun 20, 2022

Interestingly, if I comment out _POSIX_C_SOURCE,
-std=c99 compilation mode works fine,
but as a consequence, I see a mixture of clock_t and CLOCK_MONOTONIC,
depending on which unit includes timefn.h.

In file included from benchfn.c:20:                                                                                                                                                                                                                                                                             │·
timefn.h:80:6: warning: #warning "uses C90 clock_t" [-Wcpp]                                                                                                                                                                                                                                                     │·
   80 |     #warning "uses C90 clock_t"                                                                                                                                                                                                                                                                         │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/dibio.o                                                                                                                                                                                                                                                            │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/fileio.o                                                                                                                                                                                                                                                           │·
In file included from benchzstd.c:31:                                                                                                                                                                                                                                                                           │·
timefn.h:73:6: warning: #warning "uses CLOCK_MONOTONIC" [-Wcpp]                                                                                                                                                                                                                                                 │·
   73 |     #warning "uses CLOCK_MONOTONIC"                                                                                                                                                                                                                                                                     │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/fileio_asyncio.o                                                                                                                                                                                                                                                   │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/timefn.o                                                                                                                                                                                                                                                           │·
In file included from dibio.c:31:                                                                                                                                                                                                                                                                               │·
timefn.h:73:6: warning: #warning "uses CLOCK_MONOTONIC" [-Wcpp]                                                                                                                                                                                                                                                 │·
   73 |     #warning "uses CLOCK_MONOTONIC"                                                                                                                                                                                                                                                                     │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
In file included from fileio.c:36:                                                                                                                                                                                                                                                                              │·
timefn.h:73:6: warning: #warning "uses CLOCK_MONOTONIC" [-Wcpp]                                                                                                                                                                                                                                                 │·
   73 |     #warning "uses CLOCK_MONOTONIC"                                                                                                                                                                                                                                                                     │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/util.o                                                                                                                                                                                                                                                             │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/zstdcli.o                                                                                                                                                                                                                                                          │·
In file included from timefn.c:13:                                                                                                                                                                                                                                                                              │·
timefn.h:80:6: warning: #warning "uses C90 clock_t" [-Wcpp]                                                                                                                                                                                                                                                     │·
   80 |     #warning "uses C90 clock_t"                                                                                                                                                                                                                                                                         │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
CC obj/conf_63ad40fbee40d6d23986334cfd96df82/zstdcli_trace.o                                                                                                                                                                                                                                                    │·
In file included from fileio_common.h:21,                                                                                                                                                                                                                                                                       │·
                 from fileio_asyncio.c:23:                                                                                                                                                                                                                                                                      │·
timefn.h:73:6: warning: #warning "uses CLOCK_MONOTONIC" [-Wcpp]                                                                                                                                                                                                                                                 │·
   73 |     #warning "uses CLOCK_MONOTONIC"                                                                                                                                                                                                                                                                     │·
      |      ^~~~~~~                                                                                                                                                                                                                                                                                            │·
In file included from zstdcli_trace.c:16:                                                                                                                                                                                                                                                                       │·
timefn.h:80:6: warning: #warning "uses C90 clock_t" [-Wcpp]                         
8000
                                                                                                                                                                                                                            │·
   80 |     #warning "uses C90 clock_t"                                                                                                                                                                                                                                                                         │·
      |      ^~~~~~~

This can't be good.
The unit is necessarily compiled once, with one mode, or the other, not both.
I also noticed wide measurement variations, nowhere near as stable as timespec_get() nor clock_t only.
This might be a reason.

also : ensure that platform.h is included first,
before any standard library.

Note : this is fairly fragile,
any future change to include order can break this pattern.
And there is no automated test to detect this.
@Cyan4973
Copy link
Contributor Author
Cyan4973 commented Jun 20, 2022

This is actually a very problematic issue.
Having _POSIX_C_SOURCE defined differently depending on #include pattern, resulting in different interpretation of timefn.h interface, is a big source of trouble.

I think I fixed it, ensuring that _POSIX_C_SOURCE is always set through platform.h, which is itself always included first, before any standard library,

but that's fragile. In the future, any contributor may change or update the #include order in one of the affected files, this will probably be silent and seem harmless, but would then result in a sibtle change of interface interpretation, resulting in different typedef definition, resulting in wrong objects, at best perceived through wrong time measurements...
Worse, there is no automated test to detect such discrepancy.

@@ -95,10 +92,19 @@ UTIL_time_t UTIL_getTime(void)
/* time must be initialized, othersize it may fail msan test.
* No good reason, likely a limitation of timespec_get() for some target */
UTIL_time_t time = UTIL_TIME_INITIALIZER;
#if defined(TIMEFN_HAS_TIMESPEC_GET)
/* favor timespec_get() as first choice for c11 targets */
Copy link
Contributor
@embg embg Jun 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For testing: could we add something like asm("\n# Using timespec_get") and asm("\n# Using clock_gettime") to each branch of the ifdef? Then we could grep the generated assembly for those strings and ensure only one string is included.

(I'm not sure exactly how to insert a comment or symbol into the assembly, took the above code from https://stackoverflow.com/a/28493396/3154996. I think it is definitely possible, though).

Copy link
Contributor Author
@Cyan4973 Cyan4973 Jun 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would add some code specifically for this test.
It would have to be enabled through some dedicated setting (like a macro) since we don't want that for the general case.

Then indeed it would be possible to couple that generation with an external tool that grep the outcome and ensure it's consistent. This asm("# message") thing seems to only leave a comment in the generated assembly. So that means accessing the generated assembly and grep it.

That's some work, but it definitely looks plausible.

Copy link
Contributor
@embg embg Jun 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we can get text into the actual binary like this: asm volatile(".global message \n message:") (godbolt). I can test if this works for our situation and if so put up a PR which does it (gated to DEBUGLEVEL >= 2 or something). Agree that getting the generated assembly would require some work, hopefully that's not necessary.

Edit: it might be a problem for linking if it is inserted in multiple places, if so I can add a macro specifically for this test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this would be a welcome test capability.
As it stands, this PR is stuck as long as there is no way to reliably test timefn interface and ensure it's interpreted the same way in all units that include it.

@Cyan4973
Copy link
Contributor Author
Cyan4973 commented Jun 23, 2022

Another possibility :
change the timefn API in order to use opaque types,
so that the type interpretation is done solely within timefn.c,
and can't be different on user side depending on their #include order.

This is obviously more work, and requires refactoring timefn API as well as all existing calling sites.
Once completed though, it will eliminate this fragility on interpreting the return type the same way from all call sites.

@Cyan4973 Cyan4973 marked this pull request as draft September 20, 2022 16:33
@Cyan4973 Cyan4973 self-assigned this Dec 28, 2022
Cyan4973 added a commit that referenced this pull request Jan 13, 2023
The timer storage type is no longer dependent on OS.
This will make it possible to re-enable posix precise timers
since the timer storage type will no longer be sensible to #include order.
See #3168 for details of pbs of previous interface.

Suggestion by @terrelln
Cyan4973 added a commit that referenced this pull request Jan 13, 2023
The timer storage type is no longer dependent on OS.
This will make it possible to re-enable posix precise timers
since the timer storage type will no longer be sensible to #include order.
See #3168 for details of pbs of previous interface.

Suggestion by @terrelln
@Cyan4973
Copy link
Contributor Author

Replaced by #3423

@Cyan4973 Cyan4973 closed this Jan 18, 2023
@Cyan4973 Cyan4973 deleted the clock_gettime branch January 26, 2023 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0