5

In my question about std::thread, I was advised to use std::thread::hardware_concurrency(). I read somewhere (which I can not find it and seems like a local repository of code or something), that this feature is not implemented for versions of g++ prior to 4.8.

As a matter of fact, I was the at the same victim position as this user. The function will simply return 0. I found in this answer a user implementation. Comments on whether this answer is good or not are welcome!

So I would like to do this in my code:

unsinged int cores_n;
#if g++ version < 4.8
 cores_n = my_hardware_concurrency();
#else
 cores_n = std::thread::hardware_concurrency();
#endif

However, I could find a way to achieve this result. What should I do?

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Reading the [online documentation](https://gcc.gnu.org/onlinedocs/) might help, especially about [common pre-defined macros](https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros). – Some programmer dude Jan 15 '15 at 19:18
  • 7
    Even when `hardware_concurrency` is implemented, it cannot be relied as a direct mapping to the number of cores. This is what the standard says it returns - *The number of hardware thread contexts*. And goes on to state - *This value should only be considered to be a hint* If your machine has hyperthreading enabled, it's entirely possible the value returned will be 2x the number of cores. If you want a reliable answer, you'll need to use whatever facilities your OS provides. – Praetorian Jan 15 '15 at 19:21
  • I am reading the links, thanks Joachim! @Praetorian the answer I linked did not mention that, good point. – gsamaras Jan 15 '15 at 19:22

2 Answers2

11

There is another way than using the GCC Common Predefined Macros: Check if std::thread::hardware_concurrency() returns zero meaning the feature is not (yet) implemented.

unsigned int hardware_concurrency()
{
    unsigned int cores = std::thread::hardware_concurrency();
    return cores ? cores : my_hardware_concurrency();
}

You may be inspired by awgn's source code (GPL v2 licensed) to implement my_hardware_concurrency()

auto my_hardware_concurrency()
{
    std::ifstream cpuinfo("/proc/cpuinfo");

    return std::count(std::istream_iterator<std::string>(cpuinfo),
                      std::istream_iterator<std::string>(),
                      std::string("processor"));
}
oHo
  • 51,447
  • 27
  • 165
  • 200
  • 1
    Yes, I like that too! However, I haven't checked, but it seems good. Thanks! – gsamaras Jul 12 '15 at 14:42
  • 1
    Thank you @Daniel. There was an extra parenthesis at the end of the URL. Now the link is correct thanks to you comment. Cheers – oHo Apr 13 '18 at 09:56
1

Based on common predefined macros link, kindly provided by Joachim, I did:

int p;
#if __GNUC__ >= 5 || __GNUC_MINOR__ >= 8 // 4.8 for example
  const int P = std::thread::hardware_concurrency();
  p = (trees_no < P) ? trees_no : P;
  std::cout << P << " concurrent threads are supported.\n";
#else
  const int P = my_hardware_concurrency();
  p = (trees_no < P) ? trees_no : P;
  std::cout << P << " concurrent threads are supported.\n";
#endif
gsamaras
  • 71,951
  • 46
  • 188
  • 305