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_getaffeness和sched_setaffeness,但我认为没有任何好的示例。
3 个解决方案
#1
14
To use sched_setaffinity to make the current process run on core 7 you do this:
要使用sched_setaffeness来使当前进程在core 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_setaff矿化度和http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html。
#2
5
Don't use CPU_SETSIZE as cpusetsize parameter for sched_[set|get]affinity. The names are misleading but this is wrong. The makro 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." You have to use
不要将CPU_SETSIZE作为sched_[设置|get]的cpusetsize参数。这些名称具有误导性,但这是错误的。makro CPU_SETSIZE是(引用man 3 cpu_set)“一个大于可以存储在cpu_set_t中的最大CPU数量的值。”你必须使用
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
instead.
代替。
#3
0
Minimal runnable example
最小的可运行的例子
In this example, we get the affinity, modify it, and check if it has taken effect with 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);
} else {
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;
}
Compile and run with:
编译并运行:
gcc -std=c99 main.c
./a.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个内核都被启用了,进程在core 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?
这之所以有效,是因为关联是由子进程继承的,哪个任务集是分叉的:如何防止子进程继承CPU关联?
Tested in Ubuntu 16.04, GitHub upstream.
在ubuntu16.04测试,GitHub上游。
#1
14
To use sched_setaffinity to make the current process run on core 7 you do this:
要使用sched_setaffeness来使当前进程在core 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_setaff矿化度和http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html。
#2
5
Don't use CPU_SETSIZE as cpusetsize parameter for sched_[set|get]affinity. The names are misleading but this is wrong. The makro 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." You have to use
不要将CPU_SETSIZE作为sched_[设置|get]的cpusetsize参数。这些名称具有误导性,但这是错误的。makro CPU_SETSIZE是(引用man 3 cpu_set)“一个大于可以存储在cpu_set_t中的最大CPU数量的值。”你必须使用
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
instead.
代替。
#3
0
Minimal runnable example
最小的可运行的例子
In this example, we get the affinity, modify it, and check if it has taken effect with 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);
} else {
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;
}
Compile and run with:
编译并运行:
gcc -std=c99 main.c
./a.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个内核都被启用了,进程在core 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?
这之所以有效,是因为关联是由子进程继承的,哪个任务集是分叉的:如何防止子进程继承CPU关联?
Tested in Ubuntu 16.04, GitHub upstream.
在ubuntu16.04测试,GitHub上游。