如何在Linux中使用C或C ++为进程设置CPU亲和力?

问题描述 投票:34回答:5

有没有一种编程方法来为Linux操作系统的c / c ++设置进程的CPU亲和力。

c linux smp affinity
5个回答
47
投票

您需要使用sched_setaffinity(2)

例如,仅在CPU 0和2上运行:

sched_setaffinity(2)

((第一个参数的#define _GNU_SOURCE #include <sched.h> cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(0, &mask); CPU_SET(2, &mask); result = sched_setaffinity(0, sizeof(mask), &mask); 表示当前进程,如果要控制其他进程,则提供PID)。

另请参见0


8
投票

在进程级别使用sched_setaffinity,或者对于单个线程使用sched_getcpu(3)


3
投票

[sched_getcpu(3) + pthread_attr_setaffinity_np最小C可运行示例

[此示例摘自我在以下位置的答案:sched_setaffinity,因为该问题只是该问题的子集,因为它仅询问sched_getaffinity,而没有提及C ++,因此我认为问题不是重复的。

在此示例中,我们获得了亲和力,对其进行了修改,并检查它是否已对How to use sched_getaffinity and sched_setaffinity in Linux from C?生效。

main.c

sched_getaffinity

sched_getcpu()

编译并运行:

sched_getcpu()

样本输出:

#define _GNU_SOURCE
#include <assert.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void print_affinity() {
    cpu_set_t mask;
    long nproc, i;

    if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
        perror("sched_getaffinity");
        assert(false);
    }
    nproc = sysconf(_SC_NPROCESSORS_ONLN);
    printf("sched_getaffinity = ");
    for (i = 0; i < nproc; i++) {
        printf("%d ", CPU_ISSET(i, &mask));
    }
    printf("\n");
}

int main(void) {
    cpu_set_t mask;

    print_affinity();
    printf("sched_getcpu = %d\n", sched_getcpu());
    CPU_ZERO(&mask);
    CPU_SET(0, &mask);
    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
        perror("sched_setaffinity");
        assert(false);
    }
    print_affinity();
    /* TODO is it guaranteed to have taken effect already? Always worked on my tests. */
    printf("sched_getcpu = %d\n", sched_getcpu());
    return EXIT_SUCCESS;
}

这意味着:

  • 起初,我的所有16个内核均已启用,并且该进程在第9核(第10个核)上随机运行
  • 在将亲和力设置为仅第一个核心之后,该过程必然移至核心0(第一个核心)

通过GitHub upstream运行该程序也很有趣:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

哪个给出以下形式的输出:

sched_getaffinity = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
sched_getcpu = 9
sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 0

因此我们从一开始就看到它限制了亲和力。

这是有效的,因为相似性是由子进程继承的,taskset正在分支:taskset -c 1,3 ./a.out

在Ubuntu 16.04中测试。


2
投票

简而言之

sched_getaffinity = 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 2
sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 0

查看taskset了解更多详细信息


2
投票

我已经做出了很多努力来意识到正在发生的事情,所以我添加了这个答案来帮助像我这样的人(我在Linux Mint中使用How to prevent inheriting CPU affinity by child forked process?编译器)

unsigned long mask = 7; /* processors 0, 1, and 2 */
unsigned int len = sizeof(mask);
if (sched_setaffinity(0, len, &mask) < 0) {
    perror("sched_setaffinity");
}

但是请不要忘记将此选项添加到编译器命令中:CPU Affinity由于操作系统可能会为特定的内核分配进程,因此您可以将此gcc添加到位于#include <sched.h> cpu_set_t mask; inline void assignToThisCore(int core_id) { CPU_ZERO(&mask); CPU_SET(core_id, &mask); sched_setaffinity(0, sizeof(mask), &mask); } int main(){ //cal this: assignToThisCore(2);//assign to core 0,1,2,... return 0; } 的grub文件中,并在终端中运行-D _GNU_SOURCE来保留所需的内核

© www.soinside.com 2019 - 2024. All rights reserved.