如何区分 C++ 中的高性能和低性能 cores/threads?

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

在谈论多线程时,线程似乎被视为平等的 - 与主线程相同,但 运行紧随其后。

然而,在某些新处理器上,例如 Apple "M" series and the upcoming Intel Alder Lake 系列,并非所有线程都具有同样的性能,因为这些芯片具有独立的高性能内核和高效、较慢的内核。

并不是说没有超线程之类的东西,但这似乎对性能有更大的影响。

有没有办法在 C++ 中查询 std::thread 的属性并在哪些内核上强制执行 运行?

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

没有。在 C++ 中没有标准 API。

特定于平台的 API 确实能够为软件线程指定特定的逻辑核心(或一组此类核心)。例如,GNU 有 pthread_setaffinity_np.

请注意,这允许您为线程指定“核心 1”,但这不一定有助于获得“性能”核心,除非您知道那是哪个核心。要弄清楚这一点,您可能需要进入 OS 级别以下并进入 CPU 特定的汇编编程。据我了解,就英特尔而言,您将使用增强型硬件反馈接口。

您无法 select 使用 std::thread 将线程物理调度到 运行 的核心。参见 for more. I'd suggest using a framework like OpenMP, MPI, or you will have dig into the native Mac OS APIs to select the core for your thread to execute on.

不,C++ 标准库没有直接的方法来查询 CPU 的子类型,或者声明您希望线程在特定 CPU 上 运行。

但是 std::thread(和 jthread)确实有 .native_handle(),在大多数平台上都可以让你这样做。

如果您知道 std::thread 的线程库实现,您可以使用 native_handle() 获取底层原语,然后使用底层线程库来完成这种低级工作.

当然,这将是完全不可移植的。

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

请理解,“线程”是硬件功能的抽象,而您无法控制的某些东西(OS,内核的调度程序)负责创建和管理此抽象。 “重要性”和性能提示是该抽象的一部分(通常以线程优先级的形式呈现)。

任何破坏“线程”抽象的尝试(例如,确定核心是低性能还是高性能核心)都是错误的。例如。 OS 可能会在您发现 运行 在高性能内核上后立即将您的线程更改为低性能内核,导致您假设自己在高性能内核上,而实际上您并没有.

甚至将您的线程固定到特定核心(希望它始终使用高性能核心)can/will适得其反(导致您完成的工作减少,因为您阻止了自己当高性能 core/s 忙于做其他工作时使用“总比没有快”的低性能内核。

最大的问题是 C++ 在 OS 提供的“可能更好”的抽象之上创建了一个更差的抽象 (std::thread)。具体来说,使用 std::thread 无法设置、修改或获取线程优先级;因此,您无法控制(对于 OS、调度程序)做出良好的“负载与性能与电源管理”决策所必需的“性能提示”。

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

人们通常认为我们仍在使用 1960 年代的分时系统。别再听这些傻瓜的话了。 现代系统不允许 CPU 时间浪费在不重要的工作上,而更重要的工作等待。有效使用线程优先级是一项基本的性能要求。 其他一切(“负载与性能与电源管理”决策)必然超出您的控制范围(在“线程”抽象的另一端你正在使用)。

iPhone、iPad 和更新的 Mac 具有高性能和低性能内核是有原因的。低性能内核允许在使用尽可能少的能量的同时完成一些合理的工作量,从而使设备的电池寿命更长。这些额外的核心不只是为了好玩。如果您试图绕过它们,最终可能会给用户带来更糟糕的体验。

如果您将 C++ 标准库用于 运行 多线程,操作系统将检测到您在做什么,并采取相应的行动。如果你的任务在高性能核心上只需要 10ms,它就会被转移到低性能核心上;它足够快并且可以节省电池寿命。如果您有多个线程使用 100% 的 CPU 时间,将自动使用高性能内核(以及低性能内核)。如果您的电池电量不足,设备可以切换到所有低性能核心,这将完成更多工作您的电池电量

你真的应该考虑一下你想做什么。您应该将用户的需求放在您感知到的需求之前。除此之外,Apple 建议为您的线程分配 OS 特定的优先级,如果您做得对,这会改善行为。为线程赋予最高优先级以便获得更好的基准测试结果通常不是“做对了”。