为什么单线程进程在多个处理器/内核上执行?

假设我运行一个简单的单线程进程,如下所示:

Say I run a simple single-threaded process like the one below:

public class SirCountALot {
    public static void main(String[] args) {
        int count = 0;
        while (true) {
            count++;
        }
    }
}

(这是 Java,因为这是我熟悉的,但我怀疑这并不重要)

(This is Java because that's what I'm familiar with, but I suspect it doesn't really matter)

我有一个 i7 处理器(4 核,或 8 个计数超线程),我运行的是 64 位 Windows 7,所以我启动了 Sysinternals Process Explorer 来查看 CPU 使用情况,正如预期的那样,我看到它正在使用大约 20% 的可用 CPU.

I have an i7 processor (4 cores, or 8 counting hyperthreading), and I'm running Windows 7 64-bit so I fired up Sysinternals Process Explorer to look at the CPU usage, and as expected I see it is using around 20% of all available CPU.

但是当我切换为每个 CPU 显示 1 个图表的选项时,我看到 CPU 使用率分布在所有核心上,而不是使用 4 个核心"中的 1 个:

But when I toggle the option to show 1 graph per CPU, I see that instead of 1 of the 4 "cores" being used, the CPU usage is spread all over the cores:

相反,我期望的是 1 个核心最大化,但这仅在我将进程的亲和性设置为单个核心时才会发生.

Instead what I would expect is 1 core maxed out, but this only happens when I set the affinity for the process to a single core.

为什么工作负载会分散到不同的核心上?将工作负载分配到多个内核上会不会影响缓存或导致其他性能损失?

Why is the workload split over the separate cores? Wouldn't splitting the workload over several cores mess with the caching or incur other performance penalties?

仅仅是为了防止一个核心过热吗?还是有更深层次的原因?

Is it for the simple reason of preventing overheating of one core? Or is there some deeper reason?

我知道操作系统负责调度,但我想知道它为什么麻烦".当然,从幼稚的角度来看,将(大部分*)单线程进程固定到 1 个内核是更简单的 &更高效的方式?

I'm aware that the operating system is responsible for the scheduling, but I want to know why it "bothers". Surely from a naive viewpoint, sticking a (mostly*) single-threaded process to 1 core is the simpler & more efficient way to go?

*我说主要是单线程,因为这里有多个线程,但其中只有 2 个在做任何事情:

*I say mostly single-threaded because there's multiple theads here, but only 2 of them are doing anything:

推荐答案

操作系统负责调度.可以自由地停止一个线程并在另一个 CPU 上重新启动它.即使机器没有做任何其他事情,它也会这样做.

The OS is responsible for scheduling. It is free to stop a thread and start it again on another CPU. It will do this even if there is nothing else the machine is doing.

进程在 CPU 周围移动,因为操作系统不认为有任何理由每次都在同一个 CPU 上继续运行线程.

The process is moved around the CPUs because the OS doesn't assume there is any reason to continue running the thread on the same CPU each time.

出于这个原因,我编写了一个用于将线程锁定到 CPU 的库,这样它就不会四处移动,也不会被其他线程中断.这减少了延迟并提高了吞吐量,但确实会占用该线程的 CPU.这适用于 Linux,也许您可​​以将其调整为适用于 Windows.https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/入门

For this reason I have written a library for lock threads to a CPU so it won't move around and won't be interrupted by other threads. This reduces latency and improve throughput but does tire up a CPU for that thread. This works for Linux, perhaps you can adapt it for Windows. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started

相关文章