18

我在尝试着:

  • 在处理器固定的情况下同时运行 16 个副本(每个内核 2 个副本)

  • 在处理器固定(每个内核 2 个副本)的同时运行 8 个副本,并在某些功能(例如功能 1)完成后将处理器内核翻转到最远的内核。

我面临的问题是如何选择最远的处理器。

一些朋友建议使用 sched_getaffinity 和 sched_setaffinity 但我算没有找到任何好的例子。

4

3 回答 3

23

要使用 sched_setaffinity 使当前进程在核心 7 上运行,请执行以下操作:

cpu_set_t my_set;        /* Define your cpu_set bit mask. */
CPU_ZERO(&my_set);       /* Initialize it all to 0, i.e. no CPUs selected. */
CPU_SET(7, &my_set);     /* set the bit that represents core 7. */
sched_setaffinity(0, sizeof(cpu_set_t), &my_set); /* Set affinity of tihs process to */
                                                  /* the defined mask, i.e. only 7. */

有关更多信息,请参阅http://linux.die.net/man/2/sched_setaffinityhttp://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html

于 2012-06-30T03:50:20.213 回答
14

最小可运行示例

在这个例子中,我们获取了affinity,修改它,并检查它是否已经生效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;
}

GitHub 上游.

编译并运行:

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

意思就是:

  • 最初,我的所有 16 个内核都已启用,并且该进程在内核 9(第 10 个)上随机运行
  • 在我们将亲和性设置为仅第一个核心后,进程必然移动到核心 0(第一个)

通过以下方式运行此程序也很有趣taskset

taskset -c 1,3 ./a.out

这给出了形式的输出:

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分叉:如何防止子分叉进程继承 CPU 亲和性?

nproc默认情况下,请sched_getaffinity参见:How to find out the number of CPUs using python

蟒蛇:os.sched_getaffinityos.sched_setaffinity

请参阅:如何使用 python 找出 CPU 的数量

在 Ubuntu 16.04 中测试。

于 2018-05-01T13:55:23.837 回答
7

不要使用 CPU_SETSIZE 作为 sched_[set|get]affinity 的 cpusetsize 参数。这些名称具有误导性,但这是错误的。宏 CPU_SETSIZE 是(引用 man 3 cpu_set)“一个比可以存储在 cpu_set_t 中的最大 CPU 数量大一的值。” 你必须使用

sched_setaffinity(0, sizeof(cpu_set_t), &my_set);

反而。

于 2012-12-04T16:24:27.213 回答