当我运行多个与 CPU 核心/线程数匹配的线程时,每个线程会在单独的核心/线程上运行吗?

Posted

技术标签:

【中文标题】当我运行多个与 CPU 核心/线程数匹配的线程时,每个线程会在单独的核心/线程上运行吗?【英文标题】:When I run several threads that match the number of CPU core/threads, will each thread run on a separate core/thread? 【发布时间】:2016-07-09 15:03:15 【问题描述】:

线程由std::async(func)发起。

如果没有,我该怎么办?

【问题讨论】:

【参考方案1】:

该标准不保证您的线程将在哪些内核/超线程上运行。这取决于操作系统。

如果您想获得特定于平台的(不可移植的),那么有各种 API 来控制线程关联 - 例如(例如)Linux 上的pthread_setaffinity_np。 但我个人建议将其留给操作系统 - 除非您有非常特定需求,否则它很可能会做得很好。

【讨论】:

如果您不真正关心性能,您只能将内核的选择留给操作系统。 我同意,我不同意。以我的经验,操作系统大部分时间都会做明智/正确的事情,您无需担心(此外,这就是操作系统 for 的用途 - 对吧?)。在大多数情况下,当人们试图超越操作系统时,他们实际上最终会让事情变得更糟。在少数极少数的情况下,人们有真正的理由否决操作系统并且有足够的能力正确地做这件事,并且可以通过这样做来提高性能。但根据我的经验,这是一个非常罕见的案例。所以默认情况下;把它留给操作系统。 问题是操作系统喜欢在他们认为是为了更大的利益时随意改变事物。结果,线程被驱逐到另一个 CPU,并且所有缓存都无效。因此,您只是在申请中遇到随机且难以解释的延迟。令人讨厌的惊喜。这就是为什么在我的工作线中,执行单元总是绑定到核心。【参考方案2】:

作为对 Jesper 回答的补充,该标准为您提供了函数 std::thread::hardware_concurrency 来获取硬件线程上下文的数量(如果信息不可用,则为 0)。

线程调度的方式取决于实现。但是,您可以确定您的代码必须与数十个使用自己的线程运行的操作系统进程/服务/守护程序共享内核。

鉴于您的问题,当您提到std::async(func) 时,值得一提的是您可以强制执行启动策略,例如launch::async。一些实现提供了更好的控制,但同样,调度是依赖于实现的。

【讨论】:

以上是关于当我运行多个与 CPU 核心/线程数匹配的线程时,每个线程会在单独的核心/线程上运行吗?的主要内容,如果未能解决你的问题,请参考以下文章

CPU的核心数、线程数的关系和区别

CPU的“核心数”、“线程数”的关系和区别分别是啥?

CPU的核心数和线程数分别代表啥?

节点、cpu、cpu核、进程、线程

Java线程基础知识(状态共享与协作)

cpu个数、核数、线程数的关系