简体   繁体   English

如何从 C 在 Linux 中使用 sched_getaffinity 和 sched_setaffinity?

[英]How to use sched_getaffinity and sched_setaffinity in Linux from C?

I am trying to:我在尝试着:

  • Run 16 copies concurrently with processor pinning (2 copies per core)与处理器固定同时运行 16 个副本(每个内核 2 个副本)

  • Run 8 copies concurrently with processor pinning (2 copies per core) and flipping processor core to the furthest core after certain function say function 1 finishes.与处理器固定同时运行 8 个副本(每个内核 2 个副本),并在某些功能说功能 1 完成后将处理器内核翻转到最远的内核。

The problem I am facing is how to select the farthest processor.我面临的问题是如何选择最远的处理器。

Some friends suggested to use sched_getaffinity and sched_setaffinity but I count not find any good examples.有些朋友建议使用 sched_getaffinity 和 sched_setaffinity 但我数了数没有找到任何好的例子。

To use sched_setaffinity to make the current process run on core 7 you do this:要使用 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. */

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

Minimal runnable example最小的可运行示例

In this example, we get the affinity, modify it, and check if it has taken effect with sched_getcpu() .在这个例子中,我们获取了affinity,修改它,然后用sched_getcpu()检查它是否生效。

main.c主文件

#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 upstream . GitHub 上游.

Compile and run:编译并运行:

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

Sample output:示例输出:

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

Which means that:意思就是:

  • initially, all of my 16 cores were enabled, and the process was randomly running on core 9 (the 10th one)最初,我所有的 16 个内核都启用了,并且该进程在内核 9(第 10 个)上随机运行
  • after we set the affinity to only the first core, the process was moved necessarily to core 0 (the first one)在我们仅将亲和性设置为第一个核心后,该进程必然会移至核心 0(第一个)

It is also fun to run this program through taskset :通过taskset运行这个程序也很有趣:

taskset -c 1,3 ./a.out

Which gives output of form:这给出了以下形式的输出:

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

and so we see that it limited the affinity from the start.所以我们看到它从一开始就限制了亲和力。

This works because the affinity is inherited by child processes, which taskset is forking: How to prevent inheriting CPU affinity by child forked process?这是有效的,因为关联是由子进程继承的,哪个taskset正在分叉: 如何防止子进程继承 CPU 关联?

nproc respects sched_getaffinity by default as shown at: How to find out the number of CPUs using python默认情况下, nproc尊重sched_getaffinity ,如下所示: How to find out the number of CPUs using python

Python: os.sched_getaffinity and os.sched_setaffinity Python: os.sched_getaffinityos.sched_setaffinity

See: How to find out the number of CPUs using python请参阅: 如何使用python找出CPU的数量

Tested in Ubuntu 16.04.在 Ubuntu 16.04 中测试。

Don't use CPU_SETSIZE as cpusetsize parameter for sched_[set|get]affinity.不要使用 CPU_SETSIZE 作为 sched_[set|get]affinity 的 cpusetsize 参数。 The names are misleading but this is wrong.这些名称具有误导性,但这是错误的。 The macro CPU_SETSIZE is (quoting man 3 cpu_set) "a value one greater than the maximum CPU number that can be stored in cpu_set_t."宏 CPU_SETSIZE 是(引用 man 3 cpu_set)“比可以存储在 cpu_set_t 中的最大 CPU 数量大 1 的值”。 You have to use你必须使用

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

instead.反而。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM