将大量线程固定到单个 CPU 会导致所有内核的利用率激增

Pinning a large number of threads to a single CPU causes utilization spike on all cores

我编写了一个生成大量线程的小测试程序(在我的例子中是 4 核计算机上的 32 个线程)并使用 pthread_setaffinity_np 系统调用将它们全部固定到一个核上。

这些线程 运行 在一个循环中,它们通过标准输出报告 sched_getcpu 调用的结果,然后短暂休眠。我想看到的是,OS 如何严格遵守用户的线程固定设置(即使它们在我的情况下没有意义)。 所有线程都报告 运行 在我将它们固定到的核心上,这是我所期望的。

但是,我注意到,虽然程序处于 运行ning 状态,但所有 4 个内核的 cpu 利用率都在 100% 左右(通常在 0% 到 25% 之间)。有人可以启发我为什么会这样吗? 我原以为固定核心的利用率是最大的,而其他核心的利用率可能更高一些以进行补偿。

如有必要,我可以附加我的代码,但我认为它非常简单,因此并不是真正必要的。我在一台装有 Ubuntu 18.04.

的相当旧的 PC 上进行了测试

更新

#define _GNU_SOURCE

#include <assert.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>

#define THREADS 32
#define PINNED 3
#define MINUTE 60
#define MILLISEC 1000

void thread_main(int id);

int main(int argc, char** argv) {
    int i;
    pthread_t pthreads[THREADS];

    printf("%d threads will be pinned to cpu %d\n", THREADS, PINNED);

    for (i = 0; i < THREADS; ++i) {
        pthread_create(&pthreads[i], NULL, &thread_main, i);
    }

    sleep(MINUTE);

    return 0;
}

void thread_main(int id) {
    printf("thread %d: inititally running on cpu %d\n", id, sched_getcpu());

    pthread_t pthread = pthread_self();
    cpu_set_t cpu_set;

    CPU_ZERO(&cpu_set);
    CPU_SET(PINNED, &cpu_set);

    assert(0 == pthread_setaffinity_np(pthread, sizeof(cpu_set_t), &cpu_set));

    while (1) {
        printf("thread %d: running on cpu %d\n", id, sched_getcpu());
        //usleep(MILLISEC);
    }
}

当我关闭所有后台时 activity 利用率不是 100%,但肯定会在很大程度上影响所有 4 个核心。

@caf

If you're running these in a pseudo-terminal, then another process is receiving all of > that printf output and processing it, which requires CPU time as well. That process (your terminal, likely also Xorg) is going to show up heavily in profiles. Consider > that graphically rendering that text output is going to be far more CPU-intensive than the printf() that generates it. Try running your test process with output redirected to /dev/null.

这是正确答案,谢谢。

将输出定向到 /dev/null,CPU 使用高峰仅限于固定了所有线程的 CPU。