-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Windows: use EcoQoS for ThreadPriority::Background #148797
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
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-llvm-support Author: Tim Blechmann (timblechmann) ChangesThe SetThreadInformation API allows threads to be scheduled on the most efficient cores on the most efficient frequency. Full diff: https://github.com/llvm/llvm-project/pull/148797.diff 1 Files Affected:
diff --git a/llvm/lib/Support/Windows/Threading.inc b/llvm/lib/Support/Windows/Threading.inc
index d862dbd7f71c9..b52c6dff4e5f4 100644
--- a/llvm/lib/Support/Windows/Threading.inc
+++ b/llvm/lib/Support/Windows/Threading.inc
@@ -107,6 +107,31 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
}
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
+
+ typedef BOOL(WINAPI * SetThreadInformation_t)(
+ HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass,
+ _In_reads_bytes_(ThreadInformationSize) PVOID ThreadInformation,
+ ULONG ThreadInformationSize);
+ static const auto pfnSetThreadInformation =
+ (SetThreadInformation_t)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "SetThreadInformation");
+
+ if (pfnSetThreadInformation) {
+ if (Priority == ThreadPriority::Background) {
+ // Use EcoQoS for ThreadPriority::Background available (running on most
+ // efficent cores at the most efficient cpu frequency):
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation
+ // https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
+ THREAD_POWER_THROTTLING_STATE state;
+ memset(&state, 0, sizeof(state));
+ state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
+ state.ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
+ state.StateMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
+ pfnSetThreadInformation(GetCurrentThread(), ThreadPowerThrottling, &state,
+ sizeof(state));
+ }
+ }
+
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
// Begin background processing mode. The system lowers the resource scheduling
// priorities of the thread so that it can perform background work without
|
7f7e069
to
675d484
Compare
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.
Thanks for the changes. Just some more minor nits:
675d484
to
acf6eca
Compare
acf6eca
to
7d8dd65
Compare
The SetThreadInformation API allows threads to be scheduled on the most efficient cores on the most efficient frequency. Using this API for ThreadPriority::Background should make clangd-based IDEs a little less CPU hungry.
7d8dd65
to
5c586bf
Compare
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.
Looks good, thanks for all the changes!
✅ With the latest revision this PR passed the C/C++ code formatter. |
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.
Second thought, I think I'll change this to load the DLL directly from the system32 folder, otherwise this poses a security risk.
bearing the same name
@mstorsjo (or anyone else with Windows knowledge) - would you be able please to review this? |
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.
Looks reasonable overall, but a fix is needed to make it compile properly everywhere.
I made the change to not use |
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.
Looks ok to me, and seems to compile fine for mingw - thanks!
@timblechmann Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
On Android buildbots, it seems this PR started causing failures:
Where are these things types and identifiers supposed to be pulled from? |
hmm, they should come from processthreadsapi.h (via windows.h). makes me wonder if it requires a minimum requirement needs to be defined explicitly? |
For the case of mingw headers, these defines should be available since mingw-w64/mingw-w64@3a137bd, available in mingw-w64 v12 and v13. I'm not sure if we strictly want to require any specific minimum SDK to be used here - perhaps this can go within an |
i guess we could also just do the declarations ourselves if they aren't defined ... thoughts? |
That's also certainly possible (and there is some precedent for it - that we recently removed in 163871c), but it ends up kinda ugly (you either still need to detect - guess - whether the real declarations are available or not, or consistently use a different name to avoid conflicts if the real thing is available). It mostly depends on how complex the missing types are I guess. |
This is because
However
MinGW seems to have these unguarded by the Win10 define, but from the errors above it looks like we should somehow |
@Sharjeel-Khan Are you able to check if applying aganea@606253e on ToT fixes the issue you're seeing? |
Our buildbot pulls the new LLVM commits and rebuilds every 6 hours so I'll just wait for the next run which is at 12 pm |
No, you're drawing the wrong conclusions here. Yes, in the MS WinSDK, In mingw headers, these declarations don't have the Windows target version checks - so as long as So in order to fix building with both WinSDK targeting older versions of Windows, and older mingw-w64, we'd need to add an ifdef like what I'm suggesting. (Or manually duplicate the definition of these types.) |
He pointed to his private fork - his suggested change isn't included in the latest git main, so it won't be automatically tested by your buildbot. Can you check the version of |
I noticed after my message it was a private fork change. I began testing his change locally.
It is 7 |
Right, then there's no doubt - your headers are way too old to have the declarations for this API. I've set up fix in #151388 - I tried compiling this with older mingw-w64 headers, and it seems to fix the issue. |
The SetThreadInformation API allows threads to be scheduled on the most efficient cores on the most efficient frequency.
Using this API for ThreadPriority::Background should make clangd-based IDEs a little less CPU hungry.