开发者

Can I programmatically pick and choose which core of a multi-core CPU my thread should run on?

Or is it controlled by the开发者_StackOverflow 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?


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().)


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. :-)


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜