我在尝试着:
在处理器固定的情况下同时运行 16 个副本(每个内核 2 个副本)
在处理器固定(每个内核 2 个副本)的同时运行 8 个副本,并在某些功能(例如功能 1)完成后将处理器内核翻转到最远的内核。
我面临的问题是如何选择最远的处理器。
一些朋友建议使用 sched_getaffinity 和 sched_setaffinity 但我算没有找到任何好的例子。
要使用 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_setaffinity和http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html。
最小可运行示例
在这个例子中,我们获取了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;
}
编译并运行:
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
这给出了形式的输出:
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_getaffinity
和os.sched_setaffinity
在 Ubuntu 16.04 中测试。
不要使用 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);
反而。