[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

💻 CS/운영체제

[운영체제] 다중처리기 스케줄링

inu 2020. 4. 15. 14:56
반응형


  • 지금까지 알아본 스케줄링은 CPU 내 처리기가 하나만 존재함을 전제로 하고 이야기했다.
  • 하지만 요즘 컴퓨터에는 CPU가 하나여도 그 속에 코어가 여러 개 들어있다.
  • 즉, 듀얼코어, 쿼드코어 등의 다중처리기 시스템이 보편화되어 있다.
  • 다만 이러한 다중처리기에서 어떤 처리기는 계속 작업을 하고 어떤 처리기는 계속 쉬고 있어선 안된다. 다중처리기 시스템을 제대로 활용하려면, 서로간에 작업을 적절히 나누어 처리하도록 해야 한다. 즉, 부하공유(Load Sharing)를 제대로 수행하도록 해야 한다.
  • 다만 이렇게 할 경우 스케줄링 문제는 더욱 복잡해질 수 있다. 어떤 프로세스는 특정 프로세서의 버스에만 부착된 입출력 장치를 사용해야 할 수도 있는데, 이러한 제한 사항을 하나하나 고려해며 스케줄링을 해야하기 때문이다.

비대칭 다중 처리(Asymmetric Multiprocessing)

  • 마스터 서버 역할을 하는 하나의 처리기가 모든 스케줄링과 관련된 결정, 입출력 처리, 그 외 시스템 여타 활동을 취급한다.
  • 다른 처리기들은 사용자 코드만 수행한다.
  • 한 처리기만 시스템 자료구조에 접근하여 처리기 간의 커낼 내 자료들을 공유할 필요가 없다. 따라서 상호배재 등의 문제도 단순해 진다. (이에 대해선 추후에 자세히 배운다.)
  • 하지만 하나의 서버의 로드가 심하여 처리기 간 부하가 불균등하고 서버에 문제가 생기면 시스템 전체로 그 문제가 확산될 수 있다.

대칭 다중처리(Symmetric Multiprocessing, SMP)

  • 각 처리기가 독자적인 스케줄링 수행하는 방식.
  • 모든 프로세스가 공동의 준비큐에 있기도 하지만, 각 처리기마다 가지고 있는 프라이빗 준비큐에 있기도 한다.
  • 어쨌든 각 처리기의 스케줄러가 준비큐를 검사하여 자신이 실행할 프로세스를 선정한다.
  • 이 경우 서로 다른 프로세스가 공동의 자료에 접근 및 갱신해야하므로 스케줄러는 매우 신중하게 짜여져야 한다.
  • 서로 다른 2개의 처리기가 같은 프로세스를 선택해선 안되고, 또 프로세스들이 큐에서 사라져선 안된다.
  • 대부분의 운영체제는 이러한 대칭 다중처리를 지원한다. 이후 이야기할 운영체제의 대부분은 SMP를 대상으로 진행된다고 할 수 있다.

처리기 친화성

  • 프로세스가 특정 처리기에서 실행 중일 때 이 처리기로부터 가장 최근에 접근한 데이터가 해당 처리기내부의 캐시에 저장된다. 그 결과 처리기는 메인 메모리 접근의 횟수를 개선하여 성능을 높인다.
  • 다중처리기에서는 한 프로세스가 하나의 처리기에서만 실행되는 것이 아니라 다양한 이주로 이주된다.
  • 프로세스가 이주되면 원래 사용하던 처리기의 캐시 내용을 사용할 수 없게 되어 성능에 좋지 않은 영향을 준다.
  • 따라서, 대부분의 SMP 시스템에서는 한 처리기에서 다른 처리기로의 이주를 피하고 대신 같은 처리기에서 프로세스를 실행시키려고 한다. 이를 처리기 친화성 이라고 한다.
  • 연성 친화성(Soft Affinity) : 처리기에서 프로세스를 실행시키려고 노력하는 정책을 가지지만 이를 보장하지 않는 경우
  • 강성 친화성(Hard Affinity) : 시스템 콜을 통해 각 프로세스가 실행될 처리기를 명시할 수 있다. (리눅스, sched_setaffinity())
  • 많은 시스템들이 연성 친화성과 강성 친화성을 모두 지원한다.
  • NUMA(Non-Uniform Memory Access) 구조 : CPU와 메모리가 하나로 협쳐 하나의 보드에 탑재하고, 이러한 보드들을 병렬로 장착하여 사용하는 시스템. 한 보드의 CPU는 같은 보드의 메모리를 다른 보드의 메모리보다 빠르게 접근할 수 있다. 따라서 이 경우 특정 처리기에 친화성을 갖는 프로세스는 같은 보드의 메모리에 탑재하여 성능을 향상시킨다.

부하 균등화

  • 부하가 각 처리기에서 균등하도록 배분하는 시스템. push migration과 pull migration 두가지 접근법이 있다.
  • push migration : 특정 작업이 주기적으로 각 처리기의 부하를 검사하고 만일 불균형 상태로 밝혀지면 과부하인 처리기에서 상대적으로 덜 바쁜 처리기로 프로세스를 이동. 즉, push 시킨다.
  • pull migration : 쉬고 있는 처리기가 바쁜 처리기의 처리를 기다리고 있는 프로세스를 가져온다. 즉, pull 한다.
  • push migration과 pull migration은 서로 상호 배타적일 필요는 없고 실제로는 병렬적으로 구현된다.
  • 부하균등화는 처리기 친화성과는 서로 상충적인 관계이다. 즉, 처리기 친화성의 이점은 프로세스가 그 처리기의 캐시 메모리에 존재하는 데이터를 활용할 수 있다는 것인데, 반대로 부하 균등화는 프로세스를 한 처리기에서 다른 처리기로 이동시킴으로써 처리기 친화성의 이점을 없앤다.
  • 결국 두가지 모두를 만족시키는 절대적 규칙은 없다. 단지 어떤 시스템에서는 쉬고 있는 처리기가 바쁜 처리기로부터 항상 프로세스를 pull하지만, 어떤 프로세스에서는 불균형이 일정 수준(threadhold)를 넘을 때만 migration을 수행하기도 한다.

멀티코어 프로세서(Multicore Processors)

  • 멀티코어 : 하나의 프로세서 칩 내에 여러개의 코어를 내장한다. 이는 각 처리기가 각각의 물리칩을 하나씩 가지는 시스템보다 속도도 빠르고 적은 전력을 소모한다.
  • 운영체제 입장에서는 각 코어가 물리적으로 개별적으로 처리기를 가진 것처럼 보인다.
  • 메모리 멈춤 (Memory Stall) : 캐시 미스 등의 원인으로 발생한다.프로세서가 메모리 접근 시 메모리로부터 데이터가 가용해지기를 기다리면서 대기시간이 발생하는 것.
  • 멀티 쓰레드 멀티코어 : 이러한 메모리 멈춤 문제를 극복하기 위해 둘 이상의 쓰레드가 각 코어에 할당 될 수 있는 다중 쓰레드 코어를 구현하고 있다. 이런 다중 쓰레드 코어 구조에서는 한 쓰레드가 메모리를 기다리면서 멈추면, 코어는 다른 쓰레드로 전환이 가능하다. 즉, 메모리 멈춤 현상이 발생하면 코어는 작업 쓰레드를 다른 쓰레드로 전환되어 작업을 진행한다. 이러한 쓰레드는 하드웨어적으로 구현된다.
  • 운영체제 관점에서는 이러한 일을 수행하는 것이 소프트웨어적 쓰레드이다. 멀티 쓰레드 멀티 코어 구조가 이런 소프트웨어적 쓰레드를 실행할 수 있도록 하는 구조라고 할 수 있다.
  • 예를 들어 이중 쓰레드를 제공하는 듀얼코어 시스템의 CPU는 4개의 논리 프로세서가 운영체제에게 제공된다.
  • 예를 들어 8개의 하드웨어 쓰레드를 가진 16개의 코어를 가진 CPU는 총 128개의 논리 프로세서가 운영체제에게 제공된다.

멀티쓰레딩 방법

  • 일반적으로 멀티쓰레딩하는 데에는 거친 멀티쓰레딩과 세밀한 멀티쓰레딩 2가지 방법이 있다.
  • 거친(Coarse-grained) 멀티쓰레딩 : 한 쓰레드가 메모리 멈춤 현상으로 매우 긴 지연시간을 발생시킬 때까지 한 처리기에서 수행된다. 그러다 매우 긴 지연시간이 발생되면 다른 쓰레드로 전환한다. 이 경우 이전 쓰레드의 명령어 파이프라인이 정리되고, 새로운 쓰레드로 명령어를 채워나가야 하기 때문에 쓰레드 교환 비용이 증가한다.
  • 세밀한(Fine-grained) 멀티쓰레딩 : 명령어 싸이클의 경계에서 쓰레드 교환이 발생한다. 쓰레드 교환을 위한 회로적 지원이 필요하지만 교환 비용은 감소한다.
  • 멀티쓰레드 멀티코어 프로세서는 사실상 두 단계의 스케줄링이 필요하다. 특정 소프트웨어 쓰레드가 각 하드웨어 쓰레드(논리 프로세서) 중 어떤 하드웨어 쓰레드에서 실행되어야 하는지를 결정하는 한 단계, 각 코어가 어떤 하드웨어 쓰레드를 시행시킬 것인지 결정하는 한 단계이다. 소프웨어가 실행될 하드웨어 쓰레드를 결정하는 단계는 운영체제가 관여하여 스케쥴링한다. (지금까지 배운 스케줄링이 이에 적용된다.) 각 코어가 어떤 하드웨어 쓰레드를 실행할지 결정하는 단계는 하드웨어적 정책으로 스케쥴링된다. (너무 복잡하고 하드웨어적인 내용이라 이 정도만 설명한다. 자세히는 직접 찾아보자.)
반응형