How can I get the CPU core number from within a user-space app (Linux, C)?
Asked Answered
V

4

18

Presumably there is a library or simple asm blob that can get me the number of the current CPU that I am executing on.

Vestment answered 29/1, 2009 at 13:4 Comment(2)
I'm 100% sure that there was a question like this before but I can't find itAberrant
Its not too difficult to determine in the kernel, but I am (pretty) sure that no userspace means exists to find this out. Voted this up hoping that I am incorrect, good question :)Aiello
W
22

Use sched_getcpu to determine the CPU on which the calling thread is running. See man getcpu (the system call) and man sched_getcpu (a library wrapper). However, note what it says:

The information placed in cpu is only guaranteed to be current at the time of the call: unless the CPU affinity has been fixed using sched_setaffinity(2), the kernel might change the CPU at any time. (Normally this does not happen because the scheduler tries to minimize movements between CPUs to keep caches hot, but it is possible.) The caller must be prepared to handle the situation when cpu and node are no longer the current CPU and node.

Winifield answered 29/1, 2009 at 13:23 Comment(2)
You can also have a look at hwloc (open-mpi.org/projects/hwloc). With it you have accesses to the complete topology (cache/cores etc.) And it should be portable.Trichina
Here I provide a concrete sched_setaffinity + sched_getcpu C example: stackoverflow.com/questions/10490756/…Gymkhana
E
5

You need to do something like:

  • Call sched_getaffinity and identify the CPU bits
  • Iterate over the CPUs, doing sched_setaffinity to each one (I'm not sure if after sched_setaffinity you're guaranteed to be on the CPU, or need to yield explicitly ?)
  • Execute CPUID (asm instruction)... there is a way of getting a unique per-core ID out of one of it's outputs (see Intel docs). I vaguely recall it's the "APIC ID".
  • Build a table (a std::map ?) from APIC IDs to a CPU number or affinity mask or something.
  • If you did this on your main thread, don't forget to set sched_setaffinity back to all CPUS!

Now you can CPUID again whenever you need to and lookup which core you're on.

But I'd query why you need to do this; normally you want to take control via sched_setaffinity rather than finding out which core you're on (and even that's a pretty rare thing to want/need). (That's why I don't know the crucial detail of what to pull out of CPUID exactly, sorry!)

Update: Just learned about sched_getcpu from litb's response here. Much better! (my Debian/etch libc is too old to have it though).

Euniceeunuch answered 29/1, 2009 at 13:26 Comment(0)
R
2

I don't know of anything to get your current core id. With kernel level task/process migration, you wouldn't be guaranteed that it would remain constant for any length of time, unless you were running in some form of real-time mode.

If you want to be on a specific core, you can put use that sched_setaffinity() function or the taskset command to launch your program. I believe that these need elevated permissions to work, though. In your program, you could then run sched_getaffinity() to see the mask that was set earlier and use that as a best guess at the core on which you are executing.

Risky answered 29/1, 2009 at 13:17 Comment(0)
B
-1
sysconf(_SC_NPROCESSORS_ONLN);
Boris answered 6/2, 2009 at 13:33 Comment(2)
That worked for me. Why was your answer downvoted ? sched_* are glibc dependent, and sched_getcpu is returning an invalid number of core on my computer (Ubuntu 13.10 64bits, Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz).Sori
The reason this is downvoted is because this calles gives you the NUMBER of cores (processors), not the id of the current core (which the question asks for).Stereochrome

© 2022 - 2024 — McMap. All rights reserved.