Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I distinguish between high- and low-performance cores/threads in C++?

When talking about multi-threading, it often seems like threads are treated as equal - just the same as the main thread, but running next to it.

On some new processors, however, such as the Apple "M" series and the upcoming Intel Alder Lake series not all threads are equally as performant as these chips feature separate high-performance cores and high-efficiency, slower cores.

It’s not to say that there weren’t already things such as hyper-threading, but this seems to have a much larger performance implication.

Is there a way to query std::thread‘s properties and enforce on which cores they’ll run in C++?

like image 801
janekb04 Avatar asked Jul 19 '21 17:07

janekb04


People also ask

What is the difference between threads and cores?

Cores is an actual hardware component whereas thread is a virtual component that manages the tasks. Cores use content switching while threads use multiple CPUs for operating numerous processes. Cores require only a signal process unit whereas threads require multiple processing units.

What's the difference between performance and efficiency cores?

12th Gen CPUs integrate two types of cores into a single die: performance-cores (P-cores) and efficient-cores (E-cores). Performance-cores are: Physically larger high-performance cores designed for raw speed while maintaining efficiency. Optimized for low-latency single-threaded performance and AI workloads.

Can 2 threads run on different cores?

Yes, threads and processes can run concurrently on multi-core CPUs, so this works as you describe (regardless of how you create those threads and processes, OpenMP or otherwise). A single process or thread only runs on a single core at a time.


1 Answers

How to distinguish between high- and low-performance cores/threads in C++?

Please understand that "thread" is an abstraction of the hardware's capabilities and that something beyond your control (the OS, the kernel's scheduler) is responsible for creating and managing this abstraction. "Importance" and performance hints are part of that abstraction (typically presented in the form of a thread priority).

Any attempt to break the "thread" abstraction (e.g. determine if the core is a low-performance or high-performance core) is misguided. E.g. OS could change your thread to a low performance core immediately after you find out that you were running on a high performance core, leading you to assume that you're on a high performance core when you are not.

Even pinning your thread to a specific core (in the hope that it'll always be using a high-performance core) can/will backfire (cause you to get less work done because you've prevented yourself from using a "faster than nothing" low-performance core when high-performance core/s are busy doing other work).

The biggest problem is that C++ creates a worse abstraction (std::thread) on top of the "likely better" abstraction provided by the OS. Specifically, there's no way to set, modify or obtain the thread priority using std::thread; so you're left without any control over the "performance hints" that are necessary (for the OS, scheduler) to make good "load vs. performance vs. power management" decisions.

When talking about multi-threading, it often seems like threads are treated as equal

Often people think we're still using time-sharing systems from the 1960s. Stop listening to these fools. Modern systems do not allow CPU time to be wasted on unimportant work while more important work waits. Effective use of thread priorities is a fundamental performance requirement. Everything else ("load vs. performance vs. power management" decisions) is, by necessity, beyond your control (on the other side of the "thread" abstraction you're using).

like image 62
Brendan Avatar answered Sep 28 '22 02:09

Brendan