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

标签 c linux multithreading pthreads affinity

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

这些线程在循环中运行,通过 stdout 报告 sched_getcpu 调用的结果,然后休眠一小段时间。我想看到的是,操作系统如何严格遵守用户的线程固定设置(即使它们在我的情况下没有意义)。 所有线程都报告在我将它们固定到的核心上运行,这正是我所期望的。

但是,我注意到,程序运行时,所有 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);
    }
}

当我关闭所有后台事件时,利用率并不完全是 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。

关于c - 将大量线程固定到单个 CPU 会导致所有内核的利用率激增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51893206/

相关文章:

c - 套接字编程客户端/服务器

c - 等效的紧凑型 "Switch Case"语句

linux - 有没有办法确定 Linux 中可用视频 RAM 的数量?

c++ - CC、gcc 和 g++ 之间的区别?

c - C中的内存泄漏

linux - Docker 中的核心文件是什么?我可以删除它吗?

javascript - 在 node.js 中输出完整的错误对象

c# - 如何将 BitmapImage 从后台线程传递到 WPF 中的 UI 线程?

python - Python 2.7 脚本中的多个 SSH 连接 - 多处理与线程

c - fprintf() 线程安全吗?