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

Volker Hilsheimer volker.hilsheimer at qt.io
Thu Sep 26 17:17:42 CEST 2024



> On 24 Sep 2024, at 23:23, Mårten Nordheim via Development <development at qt-project.org> wrote:
> 
> 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


Based on my interpretation, I think we can start with a low-level but dirt-simple API that allows applications set a preferred CPU core type (e.g. Eco vs Default) on which a thread might run, together with the existing thread priority.

Coupling thread priority and preferred CPU type into a “task type” or “load category” as a convenient, higher-level abstraction can be a follow-up, utilising the former lower-level API. Good naming of those seems hard; I’d stay away from domain specific task type names like “AudioProcessing”.

Not sure if it’s useful to have a QCoreApplication API in addition to a QThread API; I’d expect that calling the static QThread setters from main() would be the same as calling the QCoreApplication setter.

Volker



More information about the Development mailing list