55

在单核 CPU 上,每个进程都在操作系统中运行,并且 CPU 从一个进程跳到另一个进程以充分利用自身。一个进程可以有许多线程,在这种情况下,CPU 在相应进程上运行时会通过这些线程运行。

现在,在多核 CPU 上:

  • 核心是在每个进程中一起运行,还是核心可以在一个特定时间点在不同进程中单独运行?例如,您有程序 A 运行两个线程。双核 CPU 可以运行这个程序的两个线程吗?如果我们使用类似OpenMP的东西,我认为答案应该是肯定的。但是,当内核在这个 OpenMP 嵌入式进程中运行时,其中一个内核可以简单地切换到另一个进程吗?

  • 对于单核创建的程序,100%运行时,为什么每个核的CPU使用率是分布的?(例如,80% 和 20% 的双核 CPU。在这种情况下,所有内核的利用率总和为 100%。)内核是否通过运行每个线程、每个进程以某种方式相互帮助? ?

4

5 回答 5

52

核心(或 CPU)是计算机中执行代码的物理元素。通常,每个内核都具有执行计算、寄存器文件、中断线等所需的所有元素。

大多数操作系统将应用程序表示为进程。这意味着应用程序有自己的地址空间(== 内存视图),操作系统确保该视图及其内容与其他应用程序隔离。

一个进程由一个或多个线程组成,这些线程通过在 CPU 上执行机器代码来执行应用程序的实际工作。操作系统确定哪个线程在哪个 CPU 上执行(通过使用巧妙的启发式方法来改善负载平衡、能源消耗等)。如果您的应用程序仅包含一个线程,那么您的整个多 CPU 系统不会对您有太大帮助,因为它仍然只会为您的应用程序使用一个 CPU。(但是,整体性能可能仍会提高,因为操作系统将在其他 CPU 上运行其他应用程序,因此它们不会与第一个 CPU 混合)。

现在回答您的具体问题:

1)操作系统通常允许您至少提示您要在哪个内核上执行某些线程。OpenMP 所做的是生成生成一定数量线程的代码,以在多个线程中分配来自程序循环的共享计算工作。它可以使用操作系统的提示机制(参见:线程关联)来执行此操作。但是,OpenMP 应用程序仍将与其他应用程序同时运行,因此操作系统可以自由地中断其中一个线程并在 CPU 上安排其他(可能不相关的)工作。实际上,根据您的情况,您可能希望应用许多不同的调度方案,但这是非常具体的,并且大多数时候您应该能够相信您的操作系统会为您做正确的事情。

2) 即使您在多核 CPU 上运行单线程应用程序,您也会注意到其他 CPU 也在工作。这来自a)同时执行其工作的操作系统和b)来自您的应用程序永远不会单独运行的事实——每个正在运行的系统都由一大堆并发执行的任务组成。检查 Windows 的任务管理器(或Linux 上的ps/top)以检查正在运行的内容。

于 2010-06-07T06:23:09.373 回答
12

另请注意,操作系统并不关心线程来自哪个进程。无论线程来自哪个进程,它通常都会将线程调度到处理器/内核。这可能导致一个进程的四个线程同时运行,就像四个进程的一个线程同时运行一样容易。

于 2010-06-07T03:59:31.680 回答
10

@BjoernD,你提到了..

.. 如果您的应用程序仅包含一个线程,那么您的整个多 CPU 系统将无济于事,因为它仍然只会为您的应用程序使用一个 CPU...

我认为即使它是一个单线程应用程序,该应用程序线程也可能在其生命周期内在不同的内核上执行。在每次抢占和稍后分配给 CPU 时,可能会为该线程分配不同的内核。

于 2013-07-20T10:16:49.050 回答
7

是的,线程和进程可以在多核 CPU 上同时运行,所以这就像你描述的那样工作(不管你如何创建这些线程和进程,OpenMP 或其他方式)。单个进程或线程一次只能在一个内核上运行。如果请求 CPU 时间的线程多于可用内核(通常是这种情况),操作系统调度程序将根据需要将线程移入和移出内核。

单线程进程在多个 CPU 或内核上运行的原因与您的操作系统有关,而与硬件的任何特性无关。一些操作系统没有“线程亲和性”的感觉——它们不关心线程在哪个处理器上运行——所以当需要重新评估正在使用的资源时(至少每秒几次),他们'将线程/进程从一个核心/CPU 移动到另一个。除了导致缓存未命中外,这通常不会影响进程的性能。

于 2010-06-07T03:45:20.217 回答
0

如果有一个线程应用程序有 10 个线程,最初它将在同一个 CPU/核心上启动。在一段时间内,由于 Linux 中的负载平衡器,多个线程将分布到其他核心/cpu。如果那里有多个这样的线程应用程序,我认为所有应用程序线程大多运行在同一个核心/cpu 上,因为线程的本地/全局在它们运行的​​核心的 l1/l2 缓存中很容易获得。移动它们脱离核心比执行时间更耗时。如果线程需要在不同的核心中运行。我认为必须向线程提供亲和信息。

于 2016-06-23T06:41:30.403 回答