OS/메모리 관리

스와핑(swapping)

검정비니 2018. 10. 7. 10:10
728x90
반응형

스와핑(swapping)




프로세스가 실행되기 위해서는 메모리 상에 있어야 하지만 필요한 경우 프로세스는 실행 도중에 임시로 보조 메모리로 교체되어 나갔다가 다시 메모리로 되돌아 올 수가 있다. 이러한 프로세스 교체 과정을 스와핑(swapping)이라고 한다.


예를 들면, 라운드 로빈(round-robin) 스케줄링을 하는 다중 프로그래밍 환경을 생각해 보자. 한 프로세스가 CPU 할당 시간이 끝나면 주 메모리 관리기(memory manager)가 이 프로세스를 보조 메모리로 내보내고 다른 프로세스를 메모리로 불러들일 수 있다. 즉, 스왑시킨다. 이러는 동안 CPU 스케줄러는 메모리 내의 다른 프로세스에게 시간 할당량을 준다. 각 프로세스가 시간 할당량을 모두 소비하면 그 프로세스도 스왑시킬 수 있다. CPU 스케줄러는 할당 시간이 만료되어 CPU를 새로 스케줄 할 때마다 메모리 관리기가 이미 메모리 내에 준비시켜 놓은 여러 프로세스들 중 하나를 고르기만 하면 된다. 이상적인 메모리 관리자는 CPU 스케줄러가 CPU 스케줄러가 CPU의 스케줄링 재조정(rescheduling)을 원할 때 다음에 실행할 작업이 메모리에 준비될 수 있도록 빠른 시간 내에 스왑 작업을 완료해야 한다. 게다가 스왑 작업을 고려하여 원할한 작업 처리가 이루어질 수 있도록 시간 할당량은 충분히 길어야 한다.






이러한 스와핑 정책은 우선순위에 근간을 둔 방식으로 바꿀 수도 있다. 더 높은 우선순위를 가진 프로세스가 도착하면, 메모리 관리기는 이 작업을 위해서 낮은 우선순위 프로세스를 디스크로 스왑시켜 내보낼 수 있다. 이 높은 우선순위 프로세스가 끝나면, 낮은 우선순위 프로세스는 다시 메모리로 스왑되어 계속 실행될 수 있다. 이러한 스와핑의 변형을 롤 인(roll-in), 롤 아웃(roll-out)이라고 한다. (낮은 우선순위 프로세스를 보조 메모리로 내보내는 과정이 롤 아웃, 다시 불러들이는 과정이 롤인)



일반적으로, 스왑되어 나갔던 프로세스가 다시 스왑되어 들어올 때, 가장 간단한 방법은 이전과 동일한 주소로 되돌아오는 방법일 것이다. 그렇게 하면 주소의 연계 문제가 가장 간단해지기 때문이다.


만약, 연계가 어셈블이나 적재 시간에 이루어지는 프로세스라면 스왑되어 나온 프로세스는 전에 있었던 기억 공간 내로 다시 스왑되어야 할 것이다. 연계가 어셈블이나 적재 시간에 이루어지는 프로세스라면 일단 실행이 시작된 후에는 다른 위치로 이동될 수 없기 때문이다.


그러나, 실행 시간에 연계가 이루어지는 프로세스라면 프로세스를 스왑하여 들여올 때 메모리 내의 빈 공간 어디라도 올 수 있게 된다.



스와핑은 보조 메모리를 필요로 하며 보통은 디스크를 사용한다. 디스크는 용량이 커서 모든 사용자 이미지를 저장하기에 충분하고, 이들 중 어느 이미지도 바로 꺼내올 수 있다.


시스템은 실행할 준비가 된 모든 프로세스를 모아 ready queue에 가지고 있어야 한다. CPU 스케줄러는 다음 프로세스를 고를 때 디스패처(dispatcher)를 호출한다. 디스패처는 이 큐에 있는 다음 프로세스가 메모리에 적재되어 있는지 확인해야 한다. 만약 없다면, 프로세스를 디스크에서 불러들여야 한다. 그런데 이 프로세스를 위한 공간이 메모리에 없다면 공간을 만들기 위해 현재 메모리에 적재되어 있는 프로세스를 내보내고 원하는 프로세스를 불러들여야 한다. 그리고 나서 CPU의 모든 레지스터를 실행해야 할 프로세스의 것으로 다시 적재하고, 제어권을 프로세스에게 넘긴다.



위의 과정에서 보다시피, 이런 스와핑 시스템에서는 문맥 교환 시간(context-switch time)이 상당히 오래 걸림을 알 수 있다.


문맥 교환 시간의 개념을 알아보기 위하여 사용자 프로세스의 크기는 10 MB이고, 보조 메모리는 초당 40MB의 전송률을 가진 디스크라고 가정해 보자. 보조 메모리로부터 이 프로세스를 전송 받는데 걸리는 시간은 다음과 같을 것이다.


10 MB / 40 (MB/sec) = 1/4 sec = 250 ms


헤드 탐색시간은 없다고 가정하고 평균 8ms의 회전 지연시간을 가정했을 때, 스왑 시간은 258ms가 된다. 우리는 한 프로세스를 스왑아웃하고  다른 프로세스를 스왑인 해야 하므로 총 스왑 시간은 약 516ms이다.



효과적인 CPU 사용을 위해서 각 프로세스의 실행 시간은 이 스왑 시간에 비해 충분히 길어야 한다.



스왑 시간의 대부분이 디스크 전송시간이라는 점을 주목해야 한다. 전송시간은 스왑될 메모리의 크기와 비례한다. 만약 512MB의 주기억장치를 갖는 컴퓨터 시스템이 있고, 운영체제가 25MB를 차지하고 있다고 가정한다면 사용자 프로세스가 사용할 수 있는 메모리의 최대 크기는 487MB가 된다. 그러나 많은 사용자 프로세스는 이보다 훨씬 작은 약 10MB 정도이다. 256MB를 스왑하는데 6.4초가 걸리는데 비해 10MB를 스왑하는 데는 258밀리초 정도가 소요된다.


일반적으로, 사용자 프로세스가 사용할 대략적인 메모리 크기를 추정하는 것보다 정확하게 얼마만큼의 메모리를 사용하고 있는지 아는 것이 더 유용하다. 그러면 스왑 시간을 줄이기 위해서 실제로 사용하는 부분만을 스왑하면 되기 때문이다. 이러한 작업이 효과적으로 이루어지기 위해서 사용자는 메모리 요구사항의 변화가 있을 때마다 시스템에게 이를 알려 주어야 한다. 따라서 동적으로 메모리를 요구하는 프로세스는 운영체제에게 메모리 요구사항의 변화를 알려줄 수 있는 request memory, release memory와 같은 system call을 사용해야 한다.



스와핑에는 또다른 주요한 고려사항이 있다. 프로세스를 스왑하려면, 해당 프로세스가 완전한 휴식 상태에 있음을 확인해야 한다. 프로세스가 입출력을 기다리는 경우에는 더욱 주의해야 한다. 메모리를 확보하기 위해 프로세스를 스왑하려고 할 때, 그 프로세스가 입출력을 기다리고 있는 중일 수 있다. 특히, 입출력 버퍼에 접근하기 위해서 비동기적으로 사용자 메모리에 접근하는 경우에는 프로세스를 스왑시킬 수 없다.


입출력 장치가 바빠서 프로세스의 입출력 요청이 이 장치의 대기 큐에 들어가 있다고 가정해 보자. 이때, 만약 원래의 프로세스를 스왑 아웃하고 다른 프로세스를 스왑 인하게 되면, 입출력 연산은 스왑되어 들어 온 프로그램에 속한 공간을 오인하고 그것을 입출력에 사용하려 할 것이다.


이러한 문제에 대한 해결책으로는 크게 두 가지 방법이 있다:


1)  입출력이 종료되지 않은 프로세스를 스왑하지 않는다.

2) 입출력은 항상 운영체제의 버퍼와만 하도록 만든다.


반응형