在 C++ 中,标准库函数是 std::hardware_concurrency,如文档中所述:
返回硬件线程上下文的数量。
请注意,这不需要与实际处理器数量匹配 或系统中可用的核心:一个系统可以支持多个 每个处理单元的线程,或限制对其资源的访问 到程序。
我的 CPU 有 4 个核心,但 hardware_concurrency 返回 8,我认为是由于英特尔超线程。我无法理解当你只有 4 个 CPU 核心时运行 8 个线程的好处。根据她在 SE 上的另一个回答:
当两个线程都启动时,它们是并发的 但他们都没有完成。
两个线程彼此并行运行,当每个线程 在同一时间段内积极使用不同 CPU 内核上的周期 时间间隔。
假设您生成了 8 个线程并且拥有 4 个 CPU 核心。你的8个线程可能是并发运行,但不是并行运行?数字 8 是硬件线程的数量,因此甚至操作系统调度程序也不会说:
对,我们有 8 个线程,但我们只有 4 个 CPU 核心,所以运行时 这8个线程,所以我们将切换使用的线程的运行 单 CPU 核心周期。
因为实际上有 8 个硬件线程,所以操作系统可以假设有 8 个核心。所以切换完全是在硬件中完成的,对吧?哪个更有效率。
然而,即使有了这种超线程技术,操作系统还是将 8 个作业交给了 CPU,硬件负责为每个线程调度 CPU 周期,最终的结果是,实际并行运行的东西只有 4 个。我应该补充一点,在我看来,效率有些低,因为硬件实际上是在竞争 4 个 CPU 核心资源的 8 个不同线程之间进行从一项作业到另一项作业的调度。
有趣的是,实际上,对于 4 个 CPU 核心,我还没有实现任何超过 3 或 4 个核心的性能提升,所以我认为我的理论是正确的。另外,我认为从 3 到 4 的增加可能只是微不足道的,这可能是因为一个线程正在等待其他线程加入(但这是另一个问题,可能是问题)。
如果上述所有内容都是正确的,那么运行比 CPU 内核更多的线程的唯一优势(即使使用超线程之类的技术)也是在相同 CPU 资源上“交错”任务,这样看起来事情是并行运行的,但每件事实际上都运行得更慢。
我不知道CPU是如何工作的,所以如果我错了,请有人解释一下。
您是对的,添加比物理核心更多的线程并不总是能带来性能提升,有时效率可能会降低。超线程可在特定场景中提供帮助,让 CPU 的执行单元比每个核心只有一个线程时更加繁忙。然而,实际的性能增益在很大程度上取决于工作负载特征以及线程在不相互干扰的情况下利用共享资源的程度。
整个主题本身就可以涵盖多个大学计算机体系结构课程,但请允许我尝试分解您提出的一些内容:
超线程有助于解决 CPU 遇到的许多问题(缓存未命中、分支预测错误等)。然而,当这些问题发生时,超线程就会发挥作用,并尝试在这些停顿期间执行另一个线程,因此得名“超线程”。当您尝试执行 CPU 指令时,超线程还提供并发性和并行性。 现在说到操作系统,它知道逻辑和物理过程,即优化和调度。当您进入物理核心的硬件方面时,调度程序决定接下来需要执行哪个线程的哪条指令。缓存和其他执行单元存在一些资源共享。对于使用这些执行单元的 CPU 相关任务,添加更多线程可能会导致争用和开销,从而降低性能。归根结底,超线程允许您使用 CPU 资源,而不是核心数量。