Notice
Recent Posts
Recent Comments
Today
Total
04-29 04:14
Archives
관리 메뉴

Jeongchul Kim

리눅스 스케줄링 본문

Linux

리눅스 스케줄링

김 정출 2015. 12. 19. 01:50

Chapter 4 리눅스 스케줄링


리눅스 운영체제는 프로세스나 후에 설명될 쓰레드에 대해 선점(preemption) 스케줄링 기법을 제공한다.

선점 스케줄링은 시분할 시스템에서 한 프로세스의 CPU 독점을 방지하기 위해 주어지는 타임 슬라이스(Time Slice)가 소진되었거나, 인터럽트나 시스템 호출 종료 시에 더 높은 우선순위의 프로세스가 발생하였음을 알았을 때 현 실행 프로세스로부터 강제로 CPU를 회수하여 다른 프로세스에 할당하는 것을 말한다.


이러한 선점 스케줄링을 사용하는 대부분의 운영체제는 보통 CPU 효율의 극대화, 프로세스에 대한 빠른 응답(response) 및 공평성의 향상 등을 위해 여러 가지 스케줄링 정책과 동적 우선순위 기법을 사용한다.


① 실시간 프로세스와 일반 프로세스 :  어떤 프로세스들은 주어진 기간 내에 스케줄을 받지 못하면 치명적인 일이나 오류가 발생하는데 이들은 실시간 프로세스라 한다. 실시간 프로세스들은 일반 프로세스보다 스케줄링의 우선순위가 매우 높게 측정된다. 정밀 제어, 군용 무기 제어 등이 실시간 프로세스의 부류에 속한다.

② 연산 위주 프로세스와 입출력 위주 프로세스 :  프로세스들은 우주 물리 관련 계산, 그래픽 애니메이션 시스템에서의 물체의 명암, 그림자, 모양 등의 계산 등과 같이 주로 CPU 연산을 많이 필요로 하는 연산 위주 프로세스(CPU bound process)와 은행과 같은 비즈니스 응용 처럼 간단한 계산 이외에는 검색과 저장 등의 입출력이 대부분인 입출력 위주 프로세스(I/O bound process)의 형태로 나눌 수 있다. 이러한 속성은 스케줄링에서 중요한 판단 기준이 된다.



4.1 성능 향상을 위한 선점 스케줄링의 고려 사항

시분할 선점 스케줄링에서 시스템 효율을 높이기 위한 일반적인 스케줄링 원칙이다.

연산 위주 프로세스보다 입출력 위주 프로세스에 높은 우선순위를 준다. 이와 같은 우선순위 할당의 이유에는 두 가지가 있다.

첫째, 입출력 위주의 프로세스를 먼저 스케줄링하면 이 프로세스는 CPU를 조금만 사용하고 입출력 대기를 위해 CPU를 반환하고 CPU는 다른 프로세스에 할당된다 . 따라서 결과적으로 CPU와 입출력 장치의 동시 작동(CPU I/O overlap)이 이루어져 자원의 활용도가 증가한다. 반대로 연산 위주로 스케줄링하면 CPU는 활용성이 높지만, 입출력 기기는 유휴 상태(overhead)가 많게 되어 장치 작동의 병렬성이 떨어지고, 자원의 활용도가 낮아진다.

둘째, 입출력 위주의 프로세스는 일반적으로 대화형 프로세스여서 빠른 응답을 원하는 경우가 많으므로 우선순위를 높게 할당한다. 그러나 일반적으로 커널은 실행 프로세스의 성격을 사전에 알 수 없으므로 프로세스들의 실행시켜 가며 CPU 활용의 자료를 모아 이를 스케쥴링에 점진적으로 반영하게 된다.


실시간 프로세스는 일반적인 프로세스와 대부분의 커널 실행 작업보다도 우선순위가 높다. 실시간 프로세스의 실행이 늦는 경우 재앙적 상황이 발생할 수 있기 때문이다.(경성 실시간 프로세스). 멀티미디어 서비스 같은 경우는 오디오(audio)와 비디오(video) 자료의 시간적 동기화가 필요한데, 이러한 시간 제약 때문에 실시간 서비스로 분류되지만, 시간 조건을 어기더라도 재앙적 상황은 발생하지 않으므로 이를 연성 실시간 프로세스라고 한다.


타임 슬라이스는 프로세스들의 평균 CPU 반환 시간보다 약간 크게 책정하는 것이 좋다. 어느 시스템에서 실행되는 프로세스들의 일반적인 특성이 유사하여 평균 CPU 반환 시간을 알 수 있다면 타임 슬라이스는 이보다 크게 주어야 한다. 그 이유는 CPU를 반환할 프로세스에서 CPU를 선점하게 되면 불필요한 문맥 교환(Context Switch) 오버헤드(Overhead)가 생기기 때문이다.


④ 일반적으로 프로세스가 시스템 호출을 하여 커널 모드 실행에서 있을 때, 프로세스의 대기 상태 전이로 CPU를 스스로 반환하기 이전에는 선점이 일어나지 않는다. 프로세스가 커널 모드 실행 중일 때 타임 슬라이스를 적용이나 기타의 이유로 이를 선점하게 되면 시스템 호출의 재진입에 의한 복잡한 커널 내부적 상호 배제 문제가 많이 발생하기 때문이다. 그러나 긴급한 실시간 프로세스가 발생하였을 때 이러한 속성은 문제가 된다. 커널 내에 프로세스가 진입해 있으면서도 이를 선점할 수 있는 기능을 제공하는 커널을 선점형 커널(preemptive kernel)이라 하는데 기능은 Linux version 2.6.x부터 제공되고 있다.



4.2 리눅스 스케줄링

리눅스 스케줄링에서 프로세스(쓰레드)들은 기본적으로 다음의 스케줄링 그룹으로 구분되는 데 이를 스케줄링 정책(policy)이라 한다.

SCHED_OTHERS : 일반적인 사용자 프로세스에 적용되는 스케줄링 정책으로 타임 슬라이스와 커널에 의해 지속적으로 변경되는 동적 우선순위를 사용한다.


SCHED_FIFO : 긴급한 실시간 프로세스에 사용되는 정책으로 모든 SCHED_OTHERS 그룹보다 높은 고정 우선순위를 가지며 타임 슬라이스의 개념이 없다. 타임 슬라이스의 개념이 없다는 의미는 해당 프로세스가 가장 높은 우선 순위를 가지고 있을 때, 입출력 요구 등에 의해 스스로 CPU를 반환하기 이전에는 CPU를 계속 사용할 수 있는 것을 의미


③ SCHED_RR : 역시 실시간 프로세스에 사용되는 정책으로 모든 SCHED_OTHERS 그룹 보다 높은 고정 우선순위를 가지며 타임 슬라이스를 준다. 같은 우선순위 등급에서는 타임 슬라이스에 의한 라운드로빈(Round-Robin) 스케줄링 기법이 적용된다.

* 라운드 로빈 스케줄링(Round-Robin Scheduling) : 타임 슬라이스가 다 소진 되었을 때 스케줄링 큐의 맨 마지막으로 삽입되어 같은 우선순위의 모든 다른 프로세스의 스케줄링 이후에 CPU를 받게 하는 스케줄링이다. 문맥 전환의 오버헤드가 큰 반면, 응답시간이 짧아지는 장점이 있어 실시간 시스템에 유리하다.


SCHED_FIFO와 SCHED_RR의 프로세스는 슈퍼 유저(root)만이 생성할 수 잇고, 고정 우선순위를 사용하므로 스케줄링 기법 상으로는 간단한 모델이다. 일반적 사용자 프로세스에 적용되는 SCHED_OTHERS 기법은, 앞서 설명한 연산 위주 프로세스와 입출력 위주 프로세스 중 후자에 우선순위를 높게 주는 정책을 반영하기 위한 것이다. 모든 프로세스는 생성 시에 기본 타임 슬라이스를 할당받고, 이는 기본 우선순위의 역할을 한다. 이러한 동적 우선순위 시스템을 이해하기 위해 리눅스 스케줄러의 SCHED-OTHERS 프로세스에 대한 우선 순위 계산 식과  타임 슬라이스 소진 시의 새로운 타임 슬라이스를 설정하는 2.4.x 경우의 계산 식을 알아본다.


* nice 값은 우선순위 계산 시의 벌점과 같이 작용, 초기 값은 0이며, (-20 ~ +20), nice 값이 작을 수록 동적 우선순위 시스템에서 높은 우선순위와 큰 타임 슬라이스를 가짐


동적 우선순위 = 남은 타임 슬라이스 + ( 20 - nice )의 비례 값;


SCHED_OTHERS 프로세스의 타임 슬라이스 소진되면 한 프로세스의 남은 타임 슬라이스를 나타내는 태스크 구조체 내의 counter의 값은 0이 되고, 다른 모든 프로세스의 타임 슬라이스가 소진되기까지 이 값에는 변화가 없고 따라서 스케줄링을 받지 못한다.

모든 프로세스의 counter 값이 0이 되면 타임 슬라이스를 재설정하게 되는데 그 방식은 다음과 같다.


새로운 타임 슬라이스 = (20-nice)의 비례 값 +1;


위에서 타임 슬라이스 소진 이전에 여러 가지 이유로 CPU를 선점당하는 경우에, 그 우선순위는 남은 타임 슬라이스에 의존함을 알 수 있다. 즉, 타임 슬라이스가 많이 남은 경우에는 CPU를 덜 사용한 것이 되고 이 경우에는 높은 우선순위를 줌을 알 수 있다.


SCHED_OTHERS 프로세스의 경우, 사용자는 직접 우선순위를 조정할 수 없고 단지 nice 값을 상향 조정할 수 있을 뿐이다.

nice를 하향 조정하려면 슈퍼 유저(root)의 권한이 필요하다. fork 시에 nice 값은 상속된다.


4.2.1 스케줄링 관련 시스템 호출

프로세스의 우선순위나 스케줄링 정책 조정을 위한 함수들은 다음과 같다. 우선 생성된 프로세스에 대해 일반적인 시분할 프로세스의 경우 SCHED_OTHERS로 설정하고, 실시간 프로세스의 경우에 SCHED_FIFO와 SCHED_RR 정책과 함께 우선순위를 줄 수 있는 함수



SETSCHEDULER(1)

#include <sched.h>


int sched_setscheduler(pid_t pid, int policy, const struct shced_param *p);

int sched_getscheduler(pid_t pid);


struct sched_param {

 ....

 int sched_priority;

 ....

};     

입력 값

       - pid ; 해당 프로세스 id(0인 경우는 자신)

       - policy : SCHED_OTHERS, SCHED_FIFO, SCHED_RR

       - sched_param : policy에 따라 구조체 내부의 sched_priority 값을 설정한다. SCHED_OTHERS인 경우는 0을 주어야 하며,

               실시간 프로세스의 경우는 1-99 범위의 값을 준다.

       - sched_getscheduler는 policy를 return 한다.

반환 값

       - 정상 : sched_setscheduler -> 0 sched_getscheduler -> policy

       - 에러 : -1


sched_setscheduler 함수는 SCHED_OTHERS일 경우는 무의미하다. 따라서 이 함수는 실시간 프로세스를 지정하고 고정 우선순위를 주는데 사용한다.









SCHED_SETPARAM(2)

#include <sched.h>


int sched_setparam(pid_t pid, const struct sched_param *p);

int sched_getparam(pid_t pid, struct_param *p);


입력 값

       - pid : 해당 프로세스 id (0인 경우 자신)

       - sched_param : policy에 따라 구조체 내부의 sched_priority 값을 설정한다. 실시간 프로세스의 경우는 1~99 범위의 값을

                    준다. SCHED_FIFO와 SCHED_RR은 슈퍼 유저(root) 만 사용할 수 있다.

       - sched_getscheduler는 sched_param 구조체를 반환한다.

반환 값

       - 정상 : 0

       - 에러 : -1



SCHED_YIELD

#include <sched.h>


int sched_yield(void);


sched_yield 함수는 커널에 재 스케줄링을 요구하여 호출 프로세스는 같은 우선 순위 등급의 큐에서 가장 뒤로 옮겨진다. sched_yield 후에, 자신 보다 높은 우선 순위의 프로세스가 없으면 호출 프로세스가 다시 스케줄을 받는다.

이와 같은 함수는 어떠한 프로세스가 어떤 조건이 만족하길 기다리는 loop을 수행할 때, 조건이 만족하지 않아도 주어진 타임 슬라이스 동안 계속 loop을 돌아 CPU 시간을 낭비하는 것을 방지하는데 사용되는 것이 보통이다.

즉, 한 번의 조건 테스트로 기다리는 조건이 만족하지 않음을 알았을 때, 다른 프로세스에 스케줄을 일단 양보하고 조건 테스트는 후에 다시 스케줄을 받았을 때 다시 하기 위한 함수이다.


while(!condition) { // 조건은 trylock이나 세마포어의 trywait 등을 예로 들 수 있다.

sched_yield();

}



NICE

#include <unistd.h>


int nice(int inc);


inc 값이 음수이면 우선순위가 증가하게 되는데, 이는 슈퍼 유저(root)만이 할 수 있다. nice 함수는 SCHED_OTHERS 프로세스의 nice 값을 조정하고 이는 타임 슬라이스와 우선순위 조정에 영향을 미친다. 단 SCHED_RR의 실시간 프로세스인 경우는 타임 슬라이스 조정에만 영향을 주고 우선순위는 고정이므로 영향을 미치지 않는다.



'Linux' 카테고리의 다른 글

메모리 관리  (0) 2015.12.19
파일 시스템  (1) 2015.12.19
프로세스와 쓰레드  (0) 2015.12.19
리눅스 활용을 위한 기본 지식  (0) 2015.12.19
Linux Overview  (0) 2015.12.19
Comments