CS/OS

[OS] 쓰레드란? - 쓰레드와 Parallelism/Concurrency

jhkimmm 2022. 1. 3. 09:25

쓰레드란?

프로세스는 실행 중인 프로그램(text segment)이며 작업의 단위이고, 쓰레드는 프로세스 내부에 있는 일련의 Execution이며 하나의 프로세스는 하나 이상의 쓰레드를 가질 수 있습니다. 그리고 각 쓰레드는 프로세스 내부에서 code, data, files는 공유하지만 각자의 Program Counter, Stack, Register를 가집니다. 

그렇다면 왜 쓰레드를 사용할까요?

  • 쓰레드는 light-weight 프로세스라고 할 수 있으므로 프로세스를 생성하는 것보다 Overhead가 적고 높은 Parallelism(병렬성)으로 인해 높은 퍼포먼스를 기대할 수 있습니다.
  • 프로세스의 생성은 resource-intensive하므로 Parallel하게 같은 task를 수행할 때 새로운 프로세스를 생성하는 것은 낭비입니다. 이때 쓰레드를 사용하면 리소스를 효율적으로 사용할 수 있습니다.
  • 쓰레드는 code, data, file을 공유하므로 IPC(Inter Process Communication)이 없이도 데이터의 공유가 쉽습니다.
  • 반응성 (유저가 컴퓨터의 작업이 빠르다고 느끼는 것), 확장성 (얼마나 많은 유저를 서비스할 수 있는가?)에도 이점이 있습니다.

Parallelism vs Concurrency

Concurrency

Concurrency

 "여러 개의 작업을 모두 동일한 정도로 실행시키는 것"을 의미합니다. 작업들은 하나의 코어에서 번갈아가면서 실행되며, 실제로 동시에 실행되는 것은 아니지만 모두 같은 정도만큼 실행되고 있습니다.

 

Parallelism

Parallelism

Parallelism이란 실제로 작업들이 동시에 수행되는 것을 의미합니다. 위 그림에서 처음 시점에 오직 T1과 T2만 parallel하게 실행된다고 할 수 있지만, 모든 task는 concurrently 하게 실행된다고 할 수 있다.

Concurrent하지만 Parallel하지 않을 수 있습니다.

 

Hyper-threading이란 용어도 있는데 이는 기술적인 용어가 아니라 인텔에서 만든 상업적인 용어입니다. 하드웨어적인 기술을 통해서 실제 물리적으로는 하나인 코어를 OS로 하여금 2개의 코어로 보이게 해주는 기술입니다.

 

Multicore Programming

멀티 쓰레딩 모델을 알아보기 전에 먼저 멀티코어 프로그래밍에 대해서 알아보겠습니다.

멀티코어 프로세서란 하나의 칩에 여러 개의 CPU가 올라가 있는 것을 의미하는데, 각 코어가 하나의 쓰레드를 실행하기 때문에 쓰레드를 통해서 더 효율적인 Parallel Run을 가능하게 합니다.

 

멀티 코어 프로그래밍을 구현하기 위해서 해결해야할 문제들은 다음과 같습니다.

- Identifying task

항상 프로그램의 모든 부분이 parallelizable한 것은 아니므로 프로그램의 어느부분이 independent하고 parallelizable한지 구별해야합니다.

- Balance

balance는 Task의 분배를 말하고 data splitting은 데이터의 분배를 의미합니다.

작업들이 코어에 비슷하게 할당되는가에 대한 문제입니다.

- Data spliting

코어들이 작업을 수행할 때 데이터를 분배하는 것은 쉽지않습니다. 단순히 데이터를 같은 크기로 쪼개서 분배하는 것이 아니라 전략이 필요합니다.

- Data dependency

어떤 task 다른 데이터에 의존적이어서 synchronize가 필요할 수 있습니다.

Data dependecy가 parallelism degree 결정합니다.

- Testing and debugging

멀티코어 프로그래밍은 테스팅과 디버깅이 어렵습니다.

 

Multi Threading Model

쓰레드는 유저 쓰레드와 커널 쓰레드로 구분할 수 있으며 각 쓰레드는 다음과 같은 특징을 가지고 있습니다.

User Thread

User Thread

유저 쓰레드는 커널로 부터 어떤 도움도 받지 않고 유저 레벨 어플리케이션처럼 작동합니다. Java와 같은 프로그램으로 멀티 쓰레딩을 구현하는 경우에 해당하며 유저 레벨 쓰레드의 모든 Operation와 TCB(Thread Control Block)은 유저 레벨의 라이브러리에서 관리됩니다.

커널은 얼마나 많은 유저 쓰레드가 실행 중인지 전혀 모릅니다.

Kernel Thread

Kernel Thread

유저 쓰레드와는 다르게 커널 쓰레드는 커널이 직접적으로 스케줄러를 통해 쓰레드를 컨트롤 합니다. 현재에는 모든 컴퓨터에서 커널 쓰레드를 사용한다고 볼 수 있습니다.

 

마지막으로 각 쓰레드의 장단점에 대해서 알아보겠습니다.

  장점 단점
User Thread Thread간에 context switch 시스템 콜을 호출하지 않으므로 빠르고 가볍다.

kernel mode로의 context switch가 일어나지 않는다.
 
쓰레드의 생성, 스케줄링에 시스템콜이 관여하지 않는다.
Kernel에게 보이지 않으므로 스케줄링 없다.

process block 안의 모든 thread block된다.
Kernel Thread 커널이 쓰레드를 스케줄링 있으므로 유연하다.

프로세스 내부 쓰레드의 개수에 따라 스케줄링 방식을 조정할 있다.
생성하는 것이 느리다.

user thread보다 data structure 가지므로 무겁다.