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

时间:2018-08-17 10:16:42

标签: c linux multithreading pthreads affinity

我编写了一个小的测试程序,该程序产生大量线程(在我的情况下,具有4个内核的计算机上有32个线程),并通过pthread_setaffinity_np系统调用将它们全部固定到一个内核。

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

但是,我注意到,在程序运行时,所有4个内核上的CPU利用率约为100%(通常在0%至25%之间)。有人能启发我为什么会这样吗? 我本来希望固定核心上的利用率最高,而其他核心上的利用率可能会更高一些。

如有必要,我可以附加我的代码,但我认为它非常简单,因此并不是必需的。我在装有Ubuntu 18.04的旧电脑上进行了测试。

更新

#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个核心。

1 个答案:

答案 0 :(得分:0)

  

@ caf

     

如果在伪终端中运行这些命令,则另一个进程将接收所有该printf输出并对其进行处理,这也需要CPU时间。那个过程   (您的终端,也可能是Xorg)将在个人资料中大量显示。考虑>以图形方式呈现文本输出将比生成文本输出的printf()占用更多的CPU资源。尝试运行测试过程,将输出重定向到/ dev / null。

这是正确的答案,谢谢。

在将输出定向到/dev/null的情况下,CPU使用率的峰值仅限于固定了所有线程的CPU。