개발자
WSL2 우분투 리눅스 22.04에서 c언어로 fork() 함수를 사용하여 간단한 멀티 프로세스 프로그램을 작성하였는데요. 이와 동일한 작업을 수행하는 단일 프로세스의 실행시간과 비교하였는데 수행 시간이 동일하게 나왔습니다. 시간 측정 방법은 리눅스 명령어 중 “time ./실행파일명” 을 사용하여 측정하였습니다. 해당 작업은 1~1000 까지 각 숫자에 7을 곱한 값을 출력하는 것입니다. 두 코드의 수행 시간이 동일하면 안 되고 멀티 프로세스가 단일 프로세스보다 수행시간이 작아야 하는 것으로 알고 있습니다. 아래는 저의 멀티 프로세스 코드입니다. 수행 시간이 단일 프로세스와 동일하니 멀티 프로세스가 제대로 되지 않는다고 생각됩니다... 해당 코드에서 프로세스가 제대로 생성되지 않는 이유가 뭘까요??
1#include <stdio.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <stdlib.h>
5
6int main() {
7 pid_t pid;
8 int x=1;
9 // 총 2개의 프로세스 생성
10 switch(pid=fork()) {
11 case -1: // fork 실패
12 perror("fork");
13 exit(1);
14 break;
15 case 0: // 자식 프로세스
16 x+=500;
17 break;
18 default: // 부모 프로세스
19 break;
20 }
21 // 총 4개의 프로세스 생성
22 switch(pid=fork()) {
23 case -1: // fork 실패
24 perror("fork");
25 exit(1);
26 break;
27 case 0: // 자식 프로세스
28 x+=250;
29 break;
30 default: // 부모 프로세스
31 break;
32 }
33 // 총 8개의 프로세스 생성
34 switch(pid=fork()) {
35 case -1: // fork 실패
36 perror("fork");
37 exit(1);
38 break;
39 case 0: // 자식 프로세스
40 x+=125;
41 break;
42 default: // 부모 프로세스
43 break;
44 }
45 printf("CurrentPID : %d\n", (int)getpid());
46 // 작업
47 for(int i=x; i<=x+124; i++) {
48 printf("%d ", i * 7);
49 }
50 printf("\n\n");
51}
답변 1
hyperfine 이라는 툴로 벤치마크 해보았는데요. user 모드의 cpu 사용시간보다 system 모드의 사용 시간이 길게 나오네요 [User: 147.4 µs, System: 496.2 µs] 새로운 프로세스를 할당하는 데에 시간을 많이 사용한 것으로 보입니다. 동시성의 이득을 보려면 입력이 더 커야 합니다. 다음과 같이 입력을 100배로 늘렸더니 동시성 코드가 더 빠르네요.
1//single.c
2
3#include <stdio.h>
4#include <unistd.h>
5#include <sys/types.h>
6#include <stdlib.h>
7
8int main() {
9 int x=1;
10// 작업
11 for(int i=x; i<=700000; i++) {
12 printf("%d ", i);
13 }
14 printf("\n\n");
15}
16
17//multi.c
18
19#include <stdio.h>
20#include <unistd.h>
21#include <sys/types.h>
22#include <stdlib.h>
23
24int main() {
25 pid_t pid;
26 int x=1;
27 // 총 2개의 프로세스 생성
28 switch(pid=fork()) {
29 case -1: // fork 실패
30 perror("fork");
31 exit(1);
32 break;
33 case 0: // 자식 프로세스
34 x+=50000;
35 break;
36 default: // 부모 프로세스
37 break;
38 }
39 // 총 4개의 프로세스 생성
40 switch(pid=fork()) {
41 case -1: // fork 실패
42 perror("fork");
43 exit(1);
44 break;
45 case 0: // 자식 프로세스
46 x+=25000;
47 break;
48 default: // 부모 프로세스
49 break;
50 }
51 // 총 8개의 프로세스 생성
52 switch(pid=fork()) {
53 case -1: // fork 실패
54 perror("fork");
55 exit(1);
56 break;
57 case 0: // 자식 프로세스
58 x+=12500;
59 break;
60 default: // 부모 프로세스
61 break;
62 }
63 printf("CurrentPID : %d\n", (int)getpid());
64 // 작업
65 for(int i=x; i<=x+12400; i++) {
66 printf("%d ", i * 7);
67 }
68 printf("\n\n");
69}
익명
작성자
2024년 03월 24일
작업 수행시간이 프로세스 할당 시간에 비해 매우 짧다면 동시성으로 이득을 얻을 수 없다는 것이군요! 답변 감사합니다!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
커리어리 AI 봇
GPT가 달아주는 답변입니다.
2024년 03월 23일
예시로 주신 코드의 구조상 CPU 사용 시간만 측정하는 'real time'보다는, 사용자 CPU 시간 ('user time') 및 시스템 CPU 시간 ('sys time')을 측정해야 합니다. 이 때문에 실행 시간이 단일 프로세스와 다르지 않게 보일 수 있습니다. CPU bound 작업인 숫자 계산 작업을 하고 계신 것 같은데, 멀티 프로세싱 환경에서는 IO bound 작업 또는 병렬로 처리 가능한 작업에 대해서만 실질적으로 성능 향상을 보게 됩니다. 위 같은 경우는 일반적인 CPU core 갯수보다 많은 프로세스를 생성하셔서 오히려 context switching overhead 등으로 인해 성능이 저하될 수도 있습니다. 위 코드에서 문제가 발생하는 부분은 없어 보입니다. 이것이 정확히 fork() 함수를 수행하고 있고, 자식 프로세스가 생성되며 각자의 작업을 수행하고 있는 것을 확인할 수 있습니다. 따라서 프로그램의 동작 자체에는 문제가 없어 보입니다. 결과적으로 fork()를 통해 여러개의 프로세스를 만들더라도, 병렬성이 없거나 오버헤드가 크다면 실질적인 성능 개선을 기대하기 어렵습니다. 프로세스 별로 병렬적으로 처리 가능한 작업을 분배하거나, IO 바운드 작업의 경우에만 멀티프로세싱이 더 효과적일 수 있습니다.
지금 가입하면 모든 질문의 답변을 볼 수 있어요!