How to control which core a process runs on?
To find out the number of processors instead of using /proc/cpuinfo just run:
nproc
To run a process on a group of specific processors:
taskset --cpu-list 1,2 my_command
will say that my command can only run on cpu 1 or 2.
To run a program on 4 processors doing 4 different things use parameterization. The argument to the program tells it to do something different:
for i in `seq 0 1 3`;
do
taskset --cpu-list $i my_command $i;
done
A good example of this is dealing with 8 million operation in an array so that 0 to (2mil-1) goes to processor 1, 2mil to (4mil-1) to processor 2 and so on.
You can look at the load on each process by installing htop using apt-get/yum and running at the command line:
htop
Nothing tells core "now start running this process".
The core does not see process, it only knows about executable code and various running levels and associated limitations to instructions that can be executed.
When computer boots, for sake of simplicity only one core/processor is active and actually runs any code. Then if OS is MultiProcessor capable, it activates other cores with some system specific instruction, other cores most likely pick up from exactly same spot as other core and run from there.
So what scheduler does is it looks through OS internal structures (task/process/thread queue) and picks one and marks it as running at its core. Then other scheduler instances running on other cores won't touch it until the task is in waiting state again (and not marked as pinned to specific core). After task is marked as running, scheduler executes switch to userland with task resuming at the point it was previously suspended.
Technically there is nothing whatsoever stopping cores from running exact same code at exact same time (and many unlocked functions do), but unless code is written to expect that, it will probably piss all over itself.
Scenario goes weirder with more exotic memory models (above assumes "usual" linear single working memory space) where cores don't necessarily all see same memory and there may be requirements on fetching code from other core's clutches, but it's much easier handled by simply keeping task pinned to core (AFAIK Sony PS3 architecture with SPU's is like that).
As others have mentioned, processor affinity is Operating System specific. If you want to do this outside the confines of the operating system, you're in for a lot of fun, and by that I mean pain.
That said, others have mentioned SetProcessAffinityMask
for Win32. Nobody has mentioned the Linux kernel way to set processor affinity, and so I shall. You need to use the sched_setaffinity(2)
system call. Here's a nice tutorial on how.
The command-line wrapper for this system call is taskset(1)
. e.g.taskset -c 2,3 perf stat awk 'BEGIN{for(i=0;i<100000000;i++){}}'
restricts that perf-stat of a busy-loop to running on either of core 2 or 3 (still allowing it to migrate between cores, but only between those two).
Normally the decision about which core an app will run on is made by the system. However, you can set the "affinity" for an application to a specific core to tell the OS to only run the app on that core. Normally this isn't a good idea, but there are some rare cases where it might make sense.
To do this in windows, use task manager, right click on the process, and choose "Set Affinity". You can do it programmatically in Windows using functions like SetThreadAffinityMask, SetProcessAffinityMask or SetThreadIdealProcessor.
ETA:
If you are interested in how the OS actually does the scheduling, you might want to check out these links:
Wikipedia article on context switching
Wikipedia article on scheduling
Scheduling in the linux kernel
With most modern OS's, the OS schedules a thread to execute on a core for a short slice of time. When the time slice expires, or the thread does an IO operation that causes it to voluntarily yield the core, the OS will schedule another thread to run on the core (if there are any threads ready to run). Exactly which thread is scheduled depends on the OS's scheduling algorithm.
The implementation details of exactly how the context switch occurs are CPU & OS dependent. It generally will involve a switch to kernel mode, the OS saving the state of the previous thread, loading the state of the new thread, then switching back to user mode and resuming the newly loaded thread. The context switching article I linked to above has a bit more detail about this.