리눅스에서 C 또는 C++의 프로세스에 대한 CPU 선호도를 설정하는 방법은 무엇입니까?
리눅스 운영 체제용 c/c++의 프로세스에 대한 CPU 선호도를 설정하는 프로그래밍 방식이 있습니까?
사용해야 합니다.
예를 들어 CPU 0 및 2에서만 실행하려면 다음을 수행합니다.
#define _GNU_SOURCE
#include <sched.h>
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
CPU_SET(2, &mask);
int result = sched_setaffinity(0, sizeof(mask), &mask);
(0
첫 번째 매개 변수는 현재 프로세스를 의미하며, 제어하려는 다른 프로세스인 경우 PID를 제공합니다.
참고 항목.
프로세스 수준에서 sched_setaffinity를 사용하거나 개별 스레드에 대해 pthread_attr_setaffinity_np를 사용합니다.
저는 무슨 일이 일어나고 있는지 깨닫기 위해 많은 노력을 했기 때문에 저와 같은 사람들을 돕기 위해 이 답변을 추가합니다(저는 사용합니다).gcc
컴파일러 in linux mint)
#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;
}
그러나 컴파일러 명령에 이 옵션을 추가하는 것을 잊지 마십시오.-D _GNU_SOURCE
운영 체제가 특정 코어에 프로세스를 할당할 수 있으므로 다음을 추가할 수 있습니다.GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=2,3"
다음 위치에 있는 grub 파일로/etc/default
그리고 도망가 sudo update-grub
터미널에서 원하는 코어를 예약합니다.
업데이트: 더 많은 코어를 할당하려면 다음 코드를 따르십시오.
inline void assignToThisCores(int core_id1, int core_id2)
{
CPU_ZERO(&mask1);
CPU_SET(core_id1, &mask1);
CPU_SET(core_id2, &mask1);
sched_setaffinity(0, sizeof(mask1), &mask1);
//__asm__ __volatile__ ( "vzeroupper" : : : ); // It is hear because of that bug which dirtied the AVX registers, so, if you rely on AVX uncomment it.
}
sched_setaffinity
+sched_getaffinity
최소 실행 가능 예제
이 예제는 C의 Linux에서 sched_getaffinity 및 sched_setaffinity를 사용하는 방법에 대한 답변에서 발췌되었습니다.저는 질문이 중복되지 않는다고 생각합니다. 왜냐하면 질문은 이 질문의 하위 집합이기 때문입니다.sched_getaffinity
C++에 대해서는 언급하지 않습니다.
이 예에서는 선호도를 가져와서 수정하고 에 적용되었는지 확인합니다.
주.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 업스트림.
컴파일 및 실행:
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 선호도 상속을 방지하는 방법은 무엇입니까?
파이썬:os.sched_getaffinity
그리고.os.sched_setaffinity
참고: python을 사용하여 CPU 수를 확인하는 방법
Ubuntu 16.04에서 테스트되었습니다.
요컨대
unsigned long mask = 7; /* processors 0, 1, and 2 */
unsigned int len = sizeof(mask);
if (sched_setaffinity(0, len, &mask) < 0) {
perror("sched_setaffinity");
}
cgroups와 CPU sub-system이 있는 프로그램에서 수정 없이 셸을 통과할 수도 있습니다.C그룹(v1 이상)은 일반적으로 CPU셋 하위 시스템이 있는 /sys/fs/cgroup에 마운트됩니다.예:
$ ls -l /sys/fs/cgroup/
total 0
drwxr-xr-x 15 root root 380 nov. 22 20:00 ./
drwxr-xr-x 8 root root 0 nov. 22 20:00 ../
dr-xr-xr-x 2 root root 0 nov. 22 20:00 blkio/
[...]
lrwxrwxrwx 1 root root 11 nov. 22 20:00 cpuacct -> cpu,cpuacct/
dr-xr-xr-x 2 root root 0 nov. 22 20:00 cpuset/
dr-xr-xr-x 5 root root 0 nov. 22 20:00 devices/
dr-xr-xr-x 3 root root 0 nov. 22 20:00 freezer/
[...]
CPUet에서 cpuet.cpus는 이 cgroup에 속하는 프로세스가 실행될 수 있는 CPU 범위를 정의합니다.여기서 최상위 수준에서는 모든 CPU가 시스템의 모든 프로세스에 대해 구성됩니다.여기서 시스템에는 8개의 CPU가 있습니다.
$ cd /sys/fs/cgroup/cpuset
$ cat cpuset.cpus
0-7
이 cgroup에 속하는 프로세스 목록은 cgroup.procs 파일에 나열됩니다.
$ cat cgroup.procs
1
2
3
[...]
12364
12423
12424
12425
[...]
CPU의 하위 집합이 허용되는 하위 cgroup을 생성할 수 있습니다.예를 들어 CPU 코어 1과 3이 있는 하위 c그룹을 정의합니다.
$ pwd
/sys/fs/cgroup/cpuset
$ sudo mkdir subset1
$ cd subset1
$ pwd
/sys/fs/cgroup/cpuset/subset1
$ ls -l
total 0
-rw-r--r-- 1 root root 0 nov. 22 23:28 cgroup.clone_children
-rw-r--r-- 1 root root 0 nov. 22 23:28 cgroup.procs
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.cpus
-r--r--r-- 1 root root 0 nov. 22 23:28 cpuset.effective_cpus
-r--r--r-- 1 root root 0 nov. 22 23:28 cpuset.effective_mems
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.memory_migrate
-r--r--r-- 1 root root 0 nov. 22 23:28 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.mems
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 nov. 22 23:28 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 nov. 22 23:28 notify_on_release
-rw-r--r-- 1 root root 0 nov. 22 23:28 tasks
$ cat cpuset.cpus
$ sudo sh -c "echo 1,3 > cpuset.cpus"
$ cat cpuset.cpus
1,3
프로세스를 이 cgroup으로 이동하기 전에 cpuset.mems 파일을 채워야 합니다.여기서 현재 셸을 이 새 cgroup으로 이동합니다(cgroup.procs 파일로 이동하는 프로세스의 pid만 기록합니다).
$ cat cgroup.procs
$ echo $$
4753
$ sudo sh -c "echo 4753 > cgroup.procs"
sh: 1: echo: echo: I/O error
$ cat cpuset.mems
$ sudo sh -c "echo 0 > cpuset.mems"
$ cat cpuset.mems
0
$ sudo sh -c "echo 4753 > cgroup.procs"
$ cat cgroup.procs
4753
12569
후자는 현재 셸(pid#4753)이 이제 새로 생성된 cgroup에 있음을 보여줍니다(두 번째 pid 12569는 현재 셸의 자식으로서 cgroup을 상속하는 cat의 명령어입니다).포맷된 ps 명령을 사용하면 프로세스가 실행 중인 CPU를 확인할 수 있습니다(PSR 열).
$ ps -o pid,ppid,psr,command
PID PPID PSR COMMAND
4753 2372 3 bash
12672 4753 1 ps -o pid,ppid,psr,command
현재 셸이 CPU#3에서 실행되고 cgroups를 상속하는 하위(ps 명령)가 CPU#1에서 실행되고 있음을 알 수 있습니다.
따라서 sched_setaffinity() 또는 pthread 서비스를 사용하는 대신 cgroup 트리에 CPU 집합 계층을 생성하고 해당 cgroup.procs 파일에 해당 pid를 기록하여 프로세스를 해당 계층으로 이동할 수 있습니다.
언급URL : https://stackoverflow.com/questions/280909/how-to-set-cpu-affinity-for-a-process-from-c-or-c-in-linux
'source' 카테고리의 다른 글
Mongodb를 사용하여 최근 X분 데이터를 가져오는 쿼리 (0) | 2023.07.06 |
---|---|
pip: _internal이라는 이름의 모듈이 없습니다. (0) | 2023.07.06 |
CUBE와 ROLLUP의 차이점 이해 (0) | 2023.07.06 |
하위 쿼리 결과에서 MAX()를 사용하는 방법은 무엇입니까? (0) | 2023.07.06 |
현재 컴파일러의 표준을 찾는 방법(예: C90 등) (0) | 2023.07.06 |