|
8 | 8 | #include <iterator>
|
9 | 9 | #include <algorithm>
|
10 | 10 | #include <sstream>
|
| 11 | +#include <unordered_set> |
11 | 12 |
|
12 | 13 | #if defined(__APPLE__) && defined(__MACH__)
|
13 | 14 | #include <sys/types.h>
|
|
28 | 29 |
|
29 | 30 | int32_t get_num_physical_cores() {
|
30 | 31 | #ifdef __linux__
|
31 |
| - std::ifstream cpuinfo("/proc/cpuinfo"); |
32 |
| - std::string line; |
33 |
| - while (std::getline(cpuinfo, line)) { |
34 |
| - std::size_t pos = line.find("cpu cores"); |
35 |
| - if (pos != std::string::npos) { |
36 |
| - pos = line.find(": ", pos); |
37 |
| - if (pos != std::string::npos) { |
38 |
| - try { |
39 |
| - // Extract the number and return it |
40 |
| - return static_cast<int32_t>(std::stoul(line.substr(pos + 2))); |
41 |
| - } catch (const std::invalid_argument &) { |
42 |
| - // Ignore if we could not parse |
43 |
| - } |
44 |
| - } |
| 32 | + // enumerate the set of thread siblings, num entries is num cores |
| 33 | + std::unordered_set<std::string> siblings; |
| 34 | + for (uint32_t cpu=0; cpu < UINT32_MAX; ++cpu) { |
| 35 | + std::ifstream thread_siblings("/sys/devices/system/cpu" |
| 36 | + + std::to_string(cpu) + "/topology/thread_siblings"); |
| 37 | + if (!thread_siblings.is_open()) { |
| 38 | + break; // no more cpus |
45 | 39 | }
|
| 40 | + std::string line; |
| 41 | + if (std::getline(thread_siblings, line)) { |
| 42 | + siblings.insert(line); |
| 43 | + } |
| 44 | + } |
| 45 | + if (siblings.size() > 0) { |
| 46 | + return static_cast<int32_t>(siblings.size()); |
46 | 47 | }
|
47 | 48 | #elif defined(__APPLE__) && defined(__MACH__)
|
48 | 49 | int32_t num_physical_cores;
|
|
0 commit comments