운영체제

스레드와 병행성 part1

King of Silicon Valley 2022. 7. 10. 01:14
728x90

운영체제 공룡책을 보고 정리한 내용입니다. 

Overview 

  • 스레드는 CPU이용의 기본 단위이다. 
  • 스레드는 스레드 ID, 프로그램 카운터(PC), 레지스터 집합, 스택으로 구성된다. 
  • 스레드는 같은 프로세스에 속한 다른 스레드와 코드. 데이터 섹션, 열린파일, 신호와 같은 운영체제 자원을 공유한다.
  • 전통적인 프로세스는 하나의 제어 스레드를 가지고 있다. 
  • 프로세스가 다수의 제어 스레드를 가진다면. 프로세스는 동시에 하나 이상의 작업을 수행할 수 있다. 

 

동기 (Motivation)

현대의 컴퓨터와 모바일 기기에서 작동하는 거의 모든 소프트 웨어 어플리케이션은 다중 스레드를 이용한다. 

하나의 어플리케이션은 몇 개의 스레드를 가진 독립적인 프로세스로 구현된다. 

아래에서는 다중 스레드 응용 프로그램의 몇 가지 예를 보여준다. 

 

  • 웹 브라우저는 하나의 스레드가 이미지 또는 텍스트를 표시하고 다른 스레드는 네트워크에서 데이터를 검색하도록 할 수 있다. 
  • 워드 프로세서에는 백그라운드에서 맞춤법 및 문법 검사를 수행하는 세 번째 스레드가 있을 수 있다. 

프로세스의 생성 작업은 매우 많은 시간을 소비하고 많은 자원을 필요로 하는 일이다. 

하지만 새 프로세스가 해야 할 일이 기존 프로세스가 하는 일과 동일하다면 많은 오버헤드를 감수할 필요가 없다. 

대부분은 프로세스 안에 여러 스레드를 만들어 나가는 것이 더 효율적이다. 

 

장점 (Benefits)

멀티 스레딩 프로그래밍의 장점은 다음의 4가지로 나눌 수 있다. 

 

1. 응답성(responsiveness)

  • 사용자가 시간이 많이 걸리는 연산을 시작하는 버튼을 눌렀을 때 단일스레드 어플리케이션은 그 연산이 완료될 때 까지 응답하지 않지만 시간이 오래 걸리는 연산을 별도의 비동기적 스레드에서 실행된다면 어플리케이션은 여전히 사용자에게 빠르게 응답할 수 있다. 

 

2. 자원 공유(resource sharing)

  • 프로세스는 공유 메모리와 메시지 전달 기법을 통하여만 자원을 공유할 수 있다. 
  • 반면 스레드는 자동으로 그들이 속한 프로세스의 자원들과 메모리를 공유한다. 
  • 코드와 데이터 공유의 이점은 한 응용 프로그램이 같은 주소 공간 내에 여러 개의 다른 작업을 하는 스레드를 가질 수 있다는 점이다. 

 

3. 경제성(economy)

  • 프로세스 생성을 위해 메모리와 자원을 할당하는 것은 비용이 많이 든다. 
  • 스레드는 자신이 속한 프로세스의 자원들을 공유하기 때문에 더 경제적이다. 

 

4. 규모 적응성(scalability)

  • 다중 스레드의 이점은 다중 처리기 구조에서 더욱 즉가 할 수 있다. 다중 처리기 구조에서는 각각의 스레드가 다른 처리기에서 병렬로 수행될 수 있기 때문이다. 

 

다중 코어 프로그래밍 (Multicore Programing)

 

다중 코어 아키텍처가 출현하기 전에 대부분의 컴퓨터 시스템에는 단일 프로세서만 있었으며 CPU스케줄러는 프로세스간에 빠르게 전환해 각 프로세스가 진행되도록 하여 병렬성의 환상을 제공했었다. 프로세스는 병행하게 실행되었지만 병렬로 실행 되지 않았다. 

 

중간에 나오는 암달의 법칙은 아래 블로그의 설명을 읽어보자 

https://johngrib.github.io/wiki/amdahl-s-law/#fnref:minjang-64

 

암달의 법칙 (Amdahl's law)

S = 1 / ((1-f) + f/s)

johngrib.github.io

 

프로그래밍 도전 과제 (Programing Challenges)

일반적으로 다중 코어 시스템을 위해 프로그래밍하기 위해서는 5개의 극복해야 할 도전 과제가 있다. 

 

1. 태스크 인식 (identifying tasks) 

  • 어플리케이션을 분석하여 독립된 병행 가능 태스크로 나눌 수 있는 영역을 찾는 작업이 필요하다. 
  • 이상적으로 태스크는 서로 독립적이고 개별 코어에서 실행 될 수 있어야 한다. 

2. 균형(balance)

  • 병렬로 실행될 수 있는 태스크로 찾아진 부분들이 전체 작업에 균등한 기여도를 가지도록 태스크를 나누는 것도 매우 중요하다. 
  • 디른 태스크에 비해 기여도가 낮은(병렬로 처리했을 때 효과) 작업을 위새 별도의 코어를 사용하는 것은 그만한 가치가 없다. 

3. 데이터 분리 (data spliting)

  • 어플리케이션이 독립된 태스크로 나누어지는 것처럼, 태스크가 접근하고 조작하는 데이터 또한 개별 코어에서 사용할 수 있도록 나누어져야 한다. 

4. 데이터 종속성 (data dependency)

  • 태스크가 접근하는 데이터는 둘 이상의 태스크 사이에 종속성이 없는지 검토되어야 한다. 

5. 시험 및 디버깅 

  • 프로그램이 다중 코어에서 병렬로 실행될 때, 다양한 실행 경로가 존재할 수 있다. 
  • 그런 병행 프로그램을 시험하고 디버깅 하는 것은 단일 스레드 어플리케이션을 디버깅하는 것 보다 근본적으로 훨씬 어렵다. 

병렬 실행의 유형 (Types of Parallelism)

데이터 병렬 실행: 동일한 데이터의 부분집합을 다수의 계산 코어에 분배한 뒤 각 코어에서 동일한 연산을 실행하는 데 초점을 맞춘다. 

태스크 병렬 실행: 데이터가 아니라 태스크(스레드)를 다수의 코어에 분배한다.