[Development] Thread / Process Quality of Service APIs in Qt

Mårten Nordheim marten.nordheim at qt.io
Tue Sep 24 23:23:38 CEST 2024


Hello,

For a while now there has been "Quality of Service" APIs available for threads and processes in at least Apple[0] and Windows[1].
Typically you can request either "Eco", and Default (i.e. the OS does its normal thing)

The way these work is that they will prefer running the process / thread on a CPU core that runs slower than the rest or,
with "heterogeneous CPU topology"[2], on a 'Little'[3] (ARM) or 'efficiency' core (Intel).
Note that the OS is free to run it however it sees fit, it is just a preference.

We don't currently have any API to set these preferences. Though the OS API is quite small, the question is
how do we want to have this API in Qt itself.

Looking to other frameworks/applications they have gone with an approach where "Thread Priority" is dropped
in favor of specifying a "Thread Type" / QoS type, that combines both Thread priority + QoS level.
An example of this is e.g. a "Logging/Telemetry" thread type that would set BelowNormal priority + request 'Eco' QoS level.
Or a "Rendering" thread type that could use AboveNormal priority + Default QoS.
Or "AudioProcessing", with High priority + "Eco" QoS (audio processing usually doesn't handle a lot of data at a, but still
has to complete it quickly, so an 'Eco' core would still be enough.)

We could do the same thing, but we wouldn't necessarily be able to cover all angles that our users are interested in,
so we would need to have a way for users to define these.
Adding this would probably also deprecate the thread priority APIs sometime in the longer-term.

IMO, it moves the thinking around thread priority from "is my thread high priority", to
"what does the work this thread is doing need".

The alternative is a dirt-simple API that just lets users set this variable, and we leave it to users to
call it as they see fit.

The API for thread type would be something like this:

Somewhere.h:
+ struct Q{Thread,Application}Type { ... }; // not sure about naming...

qthread.h:
+ void QThread::setThreadType(QThreadType);
+ QThreadType QThread::threadType() const;
+ static void QThread::setCurrentThreadType(QThreadType)
+ static QThreadType QThread::currentThreadType() // maybe

qcoreapplication.h:
+ void QCoreApplication::setApplicationType(QApplicationType);
+ QApplicationType QCoreApplication::applicationType() const;
+ static void QCoreApplication::setCurrentApplicationType(QApplicationType )
+ static QApplicationType QCoreApplication::currentApplicationType() // maybe

vs.

Somewhere.h:
enum class QualityOfService { Eco, Default }; 

qthread.h:
+ void QThread::setQualityOfServiceLevel(QualityOfService); // naming tbd
+ QualityOfService QThread::qualityOfServiceLevel();

qcoreapplication.h:
+ void QCoreApplication::setQualityOfServiceLevel(QualityOfService);
+ QualityOfService QCoreApplication::qualityOfServiceLevel();


Thanks,
Mårten

[0] https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html
[1] https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
[2] https://en.wikipedia.org/wiki/Heterogeneous_computing#Heterogeneous_CPU_topology
[3] https://en.wikipedia.org/wiki/ARM_big.LITTLE

(Old draft: https://codereview.qt-project.org/c/qt/qtbase/+/593378)


More information about the Development mailing list