is it possible to set the priority of a single thread to real-time priority although the process does not run under real-time priority?
The windows scheduling priorities are describing the situation clearly.
There is no thread priority called "real-time priority". The utmost priority a
thread can obtain is THREAD_PRIORITY_TIME_CRITICAL. But this does not completely
describe the threads base priority. This is also determined by the processes priority class.
For almost all process priority classes the setting of THREAD_PRIORITY_TIME_CRITICAL will
cause the thread to run in base priority of 15. One exception is the REALTIME_PRIORITY_CLASS.
A thread set to THREAD_PRIORITY_TIME_CRITICAL within a process which is set to REALTIME_PRIORITY_CLASS runs at a base priority of 31, which is the highest priority to obtain.
The combination of NORMAL_PRIORITY_CLASS and THREAD_PRIORITY_TIME_CRITICAL puts a thread already well above most other threads (also OS) but I wouldn't call this real-time.
For my point of view (and as described in the "scheduling priorities list") real-time only starts at base priorities above 15. Therefore a thread can only obtain real-time priorties, when its process has REALTIME_PRIORITY_CLASS.
This means the correct answer to your question is NO. A thread cannot obtain real-priority when its process has no real-time priority.
It is possible using SetThreadPriority but it's not recommended.
Related
My application operates on pairs of long vectors - say it adds them together to produce a vector result. Its rules state that it must completely finish with one pair before it can be given another. I would like to use multiple threads to speed things up. I am running Windows 10.
I created an OpenMP parallel for construct and divided the vector among all the threads of the team. All threads start, all threads run pretty fast, so the multithreading is effective.
But the speedup is slight, and the reason is that some of the time, one of the worker threads takes way longer than usual. I have instrumented the operation, and I see that sometimes the worker threads take a long time to start - delay varies from 20 microseconds on average to dozens of milliseconds depending on system load. The master thread does not show this delay.
That makes me think that the scheduler is taking some time to start the worker threads. The master thread is already running, so it doesn't have to wait to be started.
But here is the nub of the question: raising the priority of the process doesn't make any difference. I can raise it to high priority or even realtime priority, and I still see that startup of the worker threads is often delayed. It looks like the Windows scheduler is not fully preemptive, and sometimes lets a lower-priority thread run when a higher-priority one is eligible. Can anyone confirm this?
I have verified that the worker threads are created with the default OS priority, namely the base priority of the class of the master process. This should be higher that the priority of any running thread, I think. Or is it normal for there to be some thread with realtime priority that might be blocking my workers? I don't see one with Task Manager.
I guess one last possibility is that the task switch might take 20 usec. Is that plausible?
I have a 4-core system without hyperthreading.
Suppose you have sources of items to complete with differing priorities, and the ability to to complete items is always saturated. How do you ensure the lower priority items are not starved out completely?
I am thinking I could combine the priority of a source with the time since it was last serviced to come up with a dynamic 'effective' priority. That way, lower priority sources would slowly be raised until they were high enough to be serviced.
I didn't want to reinvent the wheel here without at least asking, in case a more elegant solution to this problem exists. Thanks!
What you are thinking is a standard idea and is called Aging.
Aging is used to ensure that jobs with lower priority will eventually complete their execution. This technique can be used to reduce starvation of low priority tasks. There are many ways to implement aging, but all have the same principle that the priority of a process should increase as it waits in the ready queue. The increase in priority may or may not be equal to the waiting time of the process.
Your current thought is to assign priority to the process. Generally you would do that by putting all the process in a min (or max, depending upon your implementation) heap and then poll the heap...
Alternatively you can assign process to priority. You do that by keeping multiple queues/lists of each priority type (highest, high, med, low, lowest etc.).
Keep multiple queues of each type;
Get item from highest priority list and finish it OR assign a time quantum to each of the high priority processes in a round robin fashion;
If all processes in high priority list are served, start serving processes from lower priority until there is something added to the higher priority list again;
As and when any process in lower priorities has been waiting for too long, remove it from that priority list and add it to the next higher priority level.
This too is a standard algorithm taught in Operating Systems.
It seems to me that one opencl command queue won't dispatch commands to more than one hardware queue. So commands in an out of order command queue are still executed one by one, just not in the order they were enqueued?
So if I want to make use of multiple hardware queues all I can do is to create multiple opencl command queues?
OOO (out of order) queues are available to meet the needs of user event dependency. Having a single queue in this type of applications can lead to a blocked queue waiting to a user event that never comes. And creating one queue per job is also non optimal.
If you want parallelism int the execution, OOO is NOT what you need. But multiple queues.
A common approach is to use a Queue for IO, and a queue for running kernels.
But you can also use a queue per thread, in a multi-thread processing scheme. IO of each thread will overlap the execution of other threads.
NOTE: nVIDIA does support parallel execution of jobs in a single queue, but that is out of the standard.
Based on msdn ,windows os schedule threads based on base prorety and uses as a boost dynamic priorety
The system treats all threads with the same priority as equal. The
system assigns time slices in a round-robin fashion to all threads
with the highest priority. If none of these threads are ready to run,
the system assigns time slices in a round-robin fashion to all threads
with the next highest priority. If a higher-priority thread becomes
available to run, the system ceases to execute the lower-priority
thread (without allowing it to finish using its time slice), and
assigns a full time slice to the higher-priority thread.
From the above quote
The system treats all threads with the same priority as equal
Does it mean that the system treats threads based on dynamic priorety?And base priorety is used just as low limit for dynamic priorety change?
Thank you
Based on msdn ,windows os schedule threads based on base prorety and uses as a boost dynamic
priorety
Well, you follow that with a nice text snipped that has NO SIGN OF A BOOST DYNAMIC PRIORITY.
More information about that is in the documentation - for example http://msdn.microsoft.com/en-us/library/windows/desktop/ms684828(v=vs.85).aspx is a good start.
In simple words, the scheduler schedules threads based on their current priority, and boost priority changes that, so they get scheduled differently.
Reading up the new Vista/Win2008 features, I wonder what is the point of the Thread Ordering Service. In other words, in which scenario the "classic" scheduler's "fair to all" policy is not sufficient, and a definite order of threads is preferrable?
To clarify. What would be a concrete application that would benefit from it?
Thanks for your answers, though.
The Thread Ordering Service does not apply to all threads, but only to those that are registered to it. You must make your program use the functionality.
The Service ensures that threads are executed in a desirable (configurable) order. That cannot be guaranteed by a "fair for all" scheduler. If your threads have no preferred execution order, the service probably does not provide extra value to you.
The Thread Ordering Service provides cooperative multi-threading in a pre-emptive multi-threading world. When you create the group you specify the maximum time slice that can be used by a thread in the group (period + timeout), and how often to run the group (period).
Your threads will then be run at most once per period, and will get an error if they exceed their maximum time slice.
I imagine this works quite well in scenarios where there's a hard response time limit.