多线程如何利用多个内核?

Posted

技术标签:

【中文标题】多线程如何利用多个内核?【英文标题】:How does multithreading utilizes multiple cores? 【发布时间】:2020-12-14 18:59:53 【问题描述】:

所以最近我学习了一些关于多线程的基础知识。我的理解是,线程是一个轻量级的进程,通过共享内存在进程下运行,而一个进程在一个CPU核下运行。

但从这个角度来看,我无法理解一些说线程利用多个内核并使整个程序执行更有效的说法。据我所知,一个进程创建的线程应该只在该特定进程下运行,这意味着它应该只在那个 CPU 内核下运行。如果我们想利用多核,我们实际上应该使用多进程来并行运行。我研究的大部分内容只是关于结论,即多线程利用多个内核,但没有一个能解释我的问题。我是不是觉得有什么不对?谢谢!

【问题讨论】:

【参考方案1】:

你的困惑就在这里:

[...] 一个进程在一个 CPU 内核下运行。

[...] 由一个进程创建的线程应该只在该特定进程下运行,这意味着它应该只在那个 CPU 内核下运行。

这不是真的。我认为您阅读的各种解释意味着任何进程都有至少一个线程(其中“线程”是由 CPU 内核运行的一系列指令)。

如果您有一个多线程程序,该进程将有多个线程(由一个 CPU 内核运行的指令序列),可以在不同的 CPU 内核上同时运行。

在任何给定时间,您的计算机上都会执行许多进程。操作系统 (OS) 是为所有这些进程分配硬件资源(CPU 内核)并决定在另一个进程使用 CPU 之前哪个进程可以使用哪些内核持续多长时间的程序。一个进程是否可以使用多个内核并不完全取决于该进程。更令人困惑的是,多线程程序可以使用比计算机 CPU 上的内核更多的线程。在这种情况下,您可以确定所有线程不会并行运行。

还有一件事:

[...] 线程利用多核,使整个程序执行更有效

我会听起来很迂腐,但比这更复杂。这取决于您所说的“有效”。我们是在谈论总计算时间、能耗..?

顺序(1 个线程)程序在功耗方面可能非常有效,但需要很长时间来计算。如果您能够使用多个线程,则可以减少计算时间,但可能会产生新的成本(线程之间的同步、针对并发访问的额外保护机制......)。

此外,多线程对于 CPU 领域之外的某些任务也无济于事。例如,除非您有一些非常具体的硬件支持,否则使用 2 个或更多并发线程从硬盘驱动器读取文件无法有效地并行化。

【讨论】:

首先感谢您的解释!然而,我仍然感到困惑:如果您有一个多线程程序,该进程将有多个线程(由 CPU 内核运行的指令序列),它们可以在不同的 CPU 内核上同时运行。 这句话是否意味着一个进程能够在与该进程不同的另一个内核上分配一个线程?根据您的回答,我认为这是由于操作系统决定进程能够访问哪个内核的原因。我说的对吗? 是的。当您的进程的第一个线程“分配”一个新线程时,它正在做的是向操作系统询问计算资源。现在操作系统被告知您的进程需要一个额外的线程,它可以为该进程分配一个新线程。

以上是关于多线程如何利用多个内核?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Matlab 中最大限度地利用多线程 CPU?

golang的线程模型——GMP模型

单核CPU如何执行多线程

多线程(线程池:ThreadPool)-C#

24多线程

ruby 有真正的多线程吗?