-
Notifications
You must be signed in to change notification settings - Fork 1.6k
<chrono>: Cache QueryPerformanceFrequency() and divide just once #653
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
<chrono>: Cache QueryPerformanceFrequency() and divide just once #653
Conversation
Actually there's no quarantee in docs that QPC is non-negative
performance difference cannot be noticed
|
I discovered the optimization is incorrect. Original code: assumes that after change the code assumes is that |
|
Now I applied different approach, this may work |
|
This is paying a significant amount of implementation complexity - I think we need a strong performance justification for making this change. Can you provide performance numbers for
|
|
@StephanTLavavej , My results are x64: It would be simpler if it would go as vNext issue, then no fake atomic needed, it would be possible to move the most of it to .cpp. |
|
Another option to achieve the same is to use |
StephanTLavavej
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI @cbezault, I pushed relatively small changes after you approved.
even with /Od
simply for physical proximity, so we'll maintain them together with the rest of the atomic machinery.
stl/inc/chrono
Outdated
| #define _CHRONO_ | ||
| #include <yvals_core.h> | ||
| #if _STL_COMPILER_PREPROCESSOR | ||
| #include <intrin0.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it strange if that makes me happy?
|
Thanks for this significant performance improvement! I would have never noticed that this was possible, so I'm glad you did. 😺 |
…nce (microsoft#653)" This reverts commit ad1a26a. # Conflicts: # stl/inc/chrono # stl/inc/xatomic.h
This was added by microsoft#694 after microsoft#653.
|
I see this has been backed out since, but is there a reason to use atomics and cache to function-local static variables? Wouldn't it be simpler and faster (no branch) to pull those variables out of the function and initialize them before main()? I see _Query_perf_frequency() in xtime.cpp is also implemented with function static atomic. This seems better to me, but maybe I'm missing something: |
|
@jpark That would add a dynamic initializer to the STL and I believe we don't have any of those right now. I seem to recall adding any causing issues with But my memory is a bit foggy on the specifics. I know we had to avoid the dynamic initializer but I don't remember the exact technical limitations forcing it. |
|
(Also I don't know if |
|
Thanks for the info. Aren't people allowed to use STL before main() in general? I've seen people declare STL collections as global variables at least. Right now, if someone calls steady_clock::now() in a global variable initializer, and it's the first call into _Query_perf_frequency(), that will call QueryPerformanceFrequency(). Thinking about it more, it may be unsafe to call my version of _Query_perf_frequency() from another initializer before main() because of not being able to control the order of initialization across translation units, so freq_cached might still be 0 with unlucky order. I don't know if the story is any different with /MT vs. /MD. |
The STL allows people to call it before main(), but if the user is a DLL they still need to observe all the usual platform requirements regarding DllMain.
Right, that's a situation we'd like to avoid because it introduces initialization order issues; and QPC isn't explicitly documented as being safe in DllMain.
It looks correct to me. It might result in 2 threads which both do QPF/QPC but they should still get correct answers. |
Description
More aggressive version of PR #646
Checklist
Be sure you've read README.md and understand the scope of this repo.
If you're unsure about a box, leave it unchecked. A maintainer will help you.
_Uglyas perhttps://eel.is/c++draft/lex.name#3.1 or there are no product code changes.
verified by an STL maintainer before automated testing is enabled on GitHub,
leave this unchecked for initial submission).
members, adding virtual functions, changing whether a type is an aggregate
or trivially copyable, etc.).
the C++ Working Draft (including any cited standards), other WG21 papers
(excluding reference implementations outside of proposed standard wording),
and LWG issues as reference material. If they were derived from a project
that's already listed in NOTICE.txt, that's fine, but please mention it.
If they were derived from any other project (including Boost and libc++,
which are not yet listed in NOTICE.txt), you must mention it here,
so we can determine whether the license is compatible and what else needs
to be done.