[Autogenerated] as we've seen,
single CPU systems are fairly easy in terms of scheduling.
The basic idea is that the highest priority thread runs and that's about it.
With multiple processors things get more complicated because we have other
factors to consider such as the preferred processors for thread the
previous processor thread was running on That makes sense because maybe
there's some data still cash in the cpus cash and of course we also have
to consider power management.
The only guarantee that we get is that the highest priority
for in the system is running somewhere.
That's the only thing we can know for sure if we take into consideration.
Power management and power conservation and numerous systems.
Things are even more complex.
And of course all these algorithms are undocumented and for good reason
because Microsoft tweaks these uh these algorithms all the time to try to
make the system better in one or another respect.
It's not really easy because Windows general purpose operating system
which means supposed to be best for everything.
But in fact the fact of the matter is that it's it
can't be the best for anything.
So it tries to be good enough for most tasks and these things change
and nobody should take any dependency on these algorithms but still I
want to give you a sense of the algorithms used in order to perform
this multi process or scheduling first we have to consider some other
aspects related to multi processing which is related to something
called affinity.
There are two types of affinity.
One of them is called soft affinity.
Soft affinity is implemented using a concept called ideal processor.
This is kind of the preferred processor.
A thread would like to run on.
The idea of soft affinity means that if the threat is unable to run on the ideal
processor it might be able to run on a different processor.
It's not mandatory but it is preferable so that there's like a very
simple load balancing between threat and processors.
So there's a default value that is being set on the process randomly and
then the next that it applies to the first thread and then the next thread
will get the next ideal processor and so on.
And it is possible to change that using the API but this is fairly rarely
used when you have a hyper threaded system then the next ideal processor
is selected from the next core rather than from the next logical processor
which is part of the same core.
And this is because we know that two logical threads that are
logical process are part of the same core.
They share level two cache.
So it's better to use different cores if possible.
This is how ideal threats are set up automatically if you're
not calling set thread ideal processor.
The other kind of affinity is called Hard affinity.
This is something that the Colonel has to abide by.
So you can say I would like this thread or this process essentially
all the threads in the process to use a certain set of processors
and we can do that like I said on a thread by thread basis or in the
process basis and the threat affinity mask cannot escape the process
affinity mask.
So in this case,
if a processor is not available to run for a threat that
requires to run that particular process or only then tough
flag the thread will not run right now.
So it means that in some cases it can actually hurt
performance instead of doing something good,
it really depends on what you're trying to do.
And the only rule you should follow here is the only rule in
performance which means uh you have to measure,
you can't really tell up front.
So you might have two very important processes on your
system and you might want to say,
let me give one process half of the processors and the other
process the other half of the processors so they can run the same
processors and so perhaps the data is going to be in this in the
cash more more frequently,
which might improve performance but there's really no way to tell these
things up front and it's best to measure to make sure that actually gives
you the result that you think you're going to get.
The other reasons why to use hard affinity.
One of them is for testing purposes,
let's um writing my system on a powerful machine but eventually the application
or whatever I'm writing is going to run on other machines,
which might be less powerful.
How can I simulate part of that different kind of
machines that are not as powerful as mine?
And one option is to limit the affinity of the
process or whatever that I'm writing.
And so that could simulate something closer to a
real scenario on other machines.
You can also use that for other um for other ways or
other scenarios for testing purposes,
such as for cases when you want to check for deadlocks
or other synchronization issues.
So I would say that this is not used for production that often,
but it is used for testing.