2

I was thinking about getting physical CPUs in Linux using C. I know, I can simply do this:

if(!(cpus = popen("cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
", "r")))
{
    // ...
}

but that's not the point, it won't work when I don't have grep installed. I came up with another idea:

  1. simply parse /proc/cpuinfo
  2. count number of physical ids:

    if(sscanf(buff, "physical id     : %d", &physicalID) == 1)
        i++;
    
  3. save them into an array:

    if(sscanf(buff, "physical id     : %d", &physicalID) == 1)
    {
        ids[i] = physicalID;
        i ++;
    }
    
  4. check if there are different numbers in the array, if so, count them = it will give me number of physical sockets (CPUs), right?

And I did it but I'm not quite sure if it will be always true ... And how about couting cores, logical CPUs and checking if hyperthreading is enabled? How can I do this with /proc/cpuinfo ?

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
Brian Brown
  • 3,873
  • 16
  • 48
  • 79
  • You might be better off by using entries in `/sys/devices/system/cpu` instead of trying to parse `/proc/cpuinfo`. For example, to get number of physical dies on your system, simply go through `/sys/devices/system/cpu/cpu*/topology/physical_package_id`, the number of dies is maximum of values you find - 1. Other things you ask for could be done the same way, without parsing the `/proc/cpuinfo`. –  Mar 27 '14 at 09:53
  • @SamiLaine: Ok, thanks but Im just curious - why is it considered a better approach? – Brian Brown Mar 27 '14 at 09:58
  • 1
    Mostly it is just an aesthetic preference: reading single values from a bunch of files instead of parsing one file means less rewriting in case the parsed file format ever changes. Of course one could forward an argument that sysfs is like how things are done today instead of using proc, but that wouldn't be completely true. –  Mar 27 '14 at 10:02
  • @SamiLaine: but was my idea ok or not? ;) will try do it your way, thanks! – Brian Brown Mar 27 '14 at 10:04
  • Well, if your idea would have been terrible, it would have been pointed out. On the other hand, if I'd have considered if to be perfect, I wouldn't have pointed out another way of doing things, would I? (For the record: I suspect we're both doing it in less-than-optimal way.) –  Mar 27 '14 at 10:06
  • /proc may not be available on some hardened systems. also, possible duplicate: http://stackoverflow.com/questions/4586405/get-number-of-cpus-in-linux-using-c – Andreas Grapentin Mar 27 '14 at 12:05
  • @AndreasGrapentin: what systems? Im interested in Ubuntu, Debian, Mint, Fedora and OpenSuse – Brian Brown Mar 27 '14 at 12:08
  • @BrianBrown it's not a question of distribution, but of configuration. Any system administrator may choose to unmount /proc, if he so desires. By the way, what do you need the cpu count of the machine for? – Andreas Grapentin Mar 27 '14 at 12:08

2 Answers2

1

lscpu returns a lot of very useful stuff about cpus, number of sockets, number of cores, number of threads per core (which could allow you to determine whether hypertheading is enabled). Not sure how it perfoms for ARM cpus etc HTH

Paul

roccap
  • 113
  • 5
  • Your answer might benefit from some re-writing in terms of answering exactly to either one or all of the questions laid out in the original question. –  Mar 27 '14 at 10:04
0

Well your understanding is correct,however you may want to refer this excellent article which cover about this concept in detail.

On the side note(as your question mentions that only C), C++11 standard has introduced the one excellent API in thread library. It returned the number of hardware thread contexts. It hides all above information(hyper threading,physical id,logical id) and all and provide the relevant information. Above all now it is in standard so this ensure the portability.

#include<thread>
#include<iostream>
int main() {
    int ncore = std::thread::hardware_concurrency();
    std::cout<<"Number Of Core:"<<ncore<<std::endl;
}
Mantosh Kumar
  • 5,659
  • 3
  • 24
  • 48