Functions for Pinning Tasks to Processors -- Restrict the range of CPUs on which your task can be schedule

Background
The task scheduler in the Windows operating system decides which task will run next, and in the case of a multiprocessor machine, on which CPU that task will run. The decision about which CPU to use is normally decided on the basis of which one has had the lightest load recently. If there is a single CPU-intensive task running on a multiprocessor machine, the probability that it will be scheduled on the same CPU for a lengthy period is quite low because the CPU on which it is running will almost certainly have a higher load than the others.
 
You ask, should this matter? The answer is YES! Because access to physical memory is slow compared to CPU speeds, modern computers put one or more levels of high speed cache between the CPU and memory. Each cache is tied to a specific CPU. When your task migrates from one CPU to another, the cache attached to the new CPU won't have the useful data that had been in the one attached to the previous CPU, so it will have to be reloaded from memory causing a delay in execution that would not have occurred if the task hadn't moved.
 
The way to avoid this situation is to restrict the range of CPUs on which your task can be scheduled from the normal set, which is all CPUs in the node, to just one. If you have multiple serial tasks running on the same node, they will usually benefit from each being assigned to a specific CPU. CPU time needed by the operating system and other tasks running on the node will be provided (appropriately) by the least heavily used CPU.
 
Files
C
Header
H:\CTC Tools\ProcAffin\Include\ProcAffin.h
C/C++ header file that protypes the functions
 
Library
H:\CTC Tools\ProcAffin\Lib\ProcAffin.lib
Contains functions:
 
BOOL SetProcAffin(int no)
Sets the task that executes it to run on processor no. It returns TRUE if it was successful and FALSE if it wasn't. The most likely reason for failure is that no is not a valid processor number.
 
BOOL ResetProcAffin(void)
Allows the task that executes it to be scheduled on any processor in the node. It should not return FALSE.
 
FORTRAN
Interface
H:\CTC Tools\ProcAffin\Include\ProcAffin.f90
Interface declaration for Fortran 90.
 
Library
H:\CTC Tools\ProcAffin\Lib\ProcAffinF.lib
Contains subroutines:
 
SET_PROC_AFFIN(NO,ERR)
Sets the task that executes it to run on processor NO. ERR is set to .TRUE. if the call was successful and .FALSE. if it wasn't.
 
RESET_PROC_AFFIN(ERR)
Sets the task that executes it to run on any processor. It should always return ERR = .TRUE.
 
Discussion
If you have more than one task on each node, it is important to pin each one to a different processor. If they are tasks in a parallel job, you can use their rank in MPI_COMM_WORLD to determine a unique processor number. If they are independent serial tasks, you will need to devise your own scheme for assuring that the processor assignments are unique.