When I create a new thread how do I know if it is running on different processor core?
My question is related to the pinToCpu function: https://github.com/nim-lang/Nim/blob/version-1-4/lib/system/threads.nim#L277
How does this function work?
When I create a new thread how do I know if it is running on different processor core?
I guess my question is "why do you want to know?" Even if you got an answer, it would be stale, since the thread could be pre-empted at any moment and resumed on a different core.
pinToCpu calls setThreadAffinityMask, which I'm guessing is implemented in C and calls some OS-specific system function, e.g. on a Unix-like OS something in the pthreads library.
CPU affinity is merely advisory guidance to an OS scheduler, not strict pinning. (This is unlike "memory pinning" via Unix calls like mlock which can be very strict at keeping pages resident in DIMMs.)
Basically, affinity just "steers" the scheduler to make it more likely a process is scheduled on particular CPUs. There is a way to find out what CPU any PID is currently running on under Linux. (top shows this, for example.)
Linux does have a kernel boot command line parameter isolcpus that can achieve true dedication of a process to a CPU, but that is not what we are reallly discussing.
This is another Linux alternative, if you know the PID and are "not the process/thread of interest":
awk '{print $39}' < /proc/PID/stat
Or you could always read the file directly from Nim, too, with roughly parseInt(readFile(path).split()[38]) where path is that /proc/PID/stat.
If you want to know from within the process/thread of interest, the C call sched_getcpu() is probably best. (Very easy to wrap in Nim).
You could use this to measure "how well affinity/the scheduler works" at keeping various processes on their target CPUs/CPU sets. Depending upon your experimental setup, there may be a bit of an impact on what you are measuring, maybe a big impact at very high poll rates and small core counts if the polling process is not also "pinned" to a different CPU set.
Anyway, @snej is 100% right that this is not a time-stable property (unless you are doing isolcpus or the equivalent on your OS). So, @mrdias should probably clarify his needs a bit more.
The OS is responsible for scheduling the threads. It is also free to move them around to satisfy the global CPU needs, including other applications.
Devs are able to give a hint to the OS scheduler so that those threads have a preferred affinity with:
Those functions are not implemented in Nim, they are OS primitives.
In terms of use case, this is a primitive for low-level multithreading implementers, i.e. if you use threadpool directly you don't need it. If you use the low-level createThread,``pinToCpu`` makes sense for workloads bottlenecked on memory speed/loading data from memory (for example working on large matrices for science or arrays of triangles for 3D). That is because each CPU core has its own L1 and L2 cache and if your workload is moved from CPU cores the cache needs to be reloaded.