Or is it controlled by the operating system? I hear the new Go language from Google has built-in features for a programmer to go that granular, or have I understood it wrong?
-
2It might be possible, but why would you want to do that? Typically the operating system can make much better decisions about which CPU to execute code on than a user-space application. – Zach Hirsch Dec 06 '09 at 08:07
-
3@Zach Some algorithms really do run better if you have fine control over what each CPU does. For example algorithms with roll-your-own spinlocks will do very poorly if a thread gets preempted, so it's best to bind to a particular core in each thread. Or I can imagine it being relevant for very CPU-bound stuff. That said... You're right, that's is kind of niche stuff. – asveikau Dec 06 '09 at 08:11
-
@asveikau Sure, but which CPU you're running on doesn't affect whether you're going to get preempted or not. One case that I can think of where it would matter is in NUMA architectures. But I doubt that the user-space program could make a decision that would benefit it better than choosing at random. – Zach Hirsch Dec 06 '09 at 08:24
-
@Zach It wouldn't be all that unreasonable to imagine two threads being assigned to the same core even if another one is running idle. By setting affinity you can more explicitly avoid that. – asveikau Dec 06 '09 at 09:00
3 Answers
It is determined by the operating system.
You can set hints for it with pthread_attr_setaffinity_np()
.
But the operating system can override you. The call above is only a suggestion your program makes to the OS.
As for Go, I haven't worked with it yet or even looked at it too deeply, but my understanding of Go is that a lot of the parallelism is rather implicit. You have co-routines (they say "go-routines", very punny) and communication between them. It seems like CPU affinity and the concept of threading itself is separate from that. That is, the language runtime could even decide to do it all on 1 CPU if it decides that's best... But again, I caution that I haven't looked at it too deeply, so I could be wrong. :-)

- 39,039
- 2
- 53
- 68
For linux os, sched_setaffinity is your answer. It's supported since linux kernel 2.5.8.
Name
sched_setaffinity, sched_getaffinity — set and get a process's CPU affinity mask
#define _GNU_SOURCE
#include <sched.h>
int sched_setaffinity( pid_t pid,
size_t cpusetsize,
cpu_set_t *mask);
int sched_getaffinity( pid_t pid,
size_t cpusetsize,
cpu_set_t *mask);
The affinity mask is actually a per-thread attribute that can be adjusted independently for each of the threads in a thread group. The value returned from a call to gettid(2) can be passed in the argument pid. Specifying pid as 0 will set the attribute for the calling thread, and passing the value returned from a call to getpid(2) will set the attribute for the main thread of the thread group. (If you are using the POSIX threads API, then use pthread_setaffinity_np(3) instead of sched_setaffinity().)

- 43,637
- 15
- 53
- 61
The answer is yes, you can programmatically choose which core a process runs on. As arsane mentioned, the answer lies with sched_set_affinity(), and then pthread_setaffinity_np() for pthreads.
Here is a nifty tutorial on how to do this with processes (which comes from an answer to this question.)
Basically, this is done using a bitmask. This means that there is an integer (say, 32 bits), and if the first bit == 1, then that process is allowed to run on processor 1. If the second bit == 1, then that process is allowed to run on processor 2. etc.
So by default, the affinity bitmask = 1...111 (32 times.) This means that "The process may run on processor 1, 2, 3, ..., 32." Of course, if you only have 2 cores, then the extra 30 bits won't apply.
However, if you set that bitmask to be: 0...010 then only "processor 2" is allowed to execute that process.
Which also explains why the maximum number of processors supported by linux is 32. (out of the box, without tweaking, x86, on much of commonly-found hardware, without clustering, etc etc).

- 1
- 1

- 18,726
- 23
- 95
- 134