Chapter 04. Thread and Concurrency
스레드란?)
스레드는 cpu 연산의 가장 작은 단위이다.
1개의 쓰레드는 registers + stack + progran counter or Instruction Pointer(다음에 시작하는 명령어를 가리키는 포인터) + thread id 등을 각자 갖는다.
Code, Data, Files 영역은 스레드끼리 공유한다.
멀티 쓰레드 프로세스를 실행하면 한 번에 1개 이상의 task를 수행할 수 있다.
스레드의 장점)
- 한 스레드가 block 되거나 긴 연산을 할 때도 나머지 스레드들은 연산을 수행할 수 있다.
- 같은 프로세스의 스레드들은 메모리와 자원을 공유한다.
- 스레드 사이의 context switch가 프로세서 간의 context switch 보다 빠르다.
- 병렬적으로 실행될 수 있다
Multicore의 장점)


위의 싱글코어 시스템에서는 Concurrency(동시성) 즉 결과적으로 여러 스레드를 실행하는 것이다.
다만 Concurrency와 Parallelism을 구분할 필요가 있다.
병렬성은 멀티코어 시스템 일 때 가질 수 있는데 이는 동시에 여러 task를 처리하는 것이다. 싱글코어 시스템에서의 동시성은 마치 병렬적으로 처리하는 것처럼 보여주지만 실제로는 계속 교환해 가면서 실행하는 것이고 진정으로 동시에 실행하는 경우(Parrallism)는 멀티코어 시스템에서만 가능하다.
Data Parallelism : 다른 data들로 서로 같은 일을 하는 것이다. 예를 들어 동시에 여러 명의 학생 정보를 조회할 때 학생 data
Task Parallelism : 같은 data 혹은 서로 다른 data를 사용해 서로 다른 일을 하는 것이다. 예를 들어 A라는 학생의 성적으로 평균, 표준편차를 동시에 구할 때
Amdahl's Law)

어떤 작업의 시간 효율을 개선할 때, 전체 작업시간에 대해 P만큼의 작업시간을 차지하는 작업의 효율을 S만큼 향상했다 가정하자. 그렇다면 전체 작업 효율은 위의 공식을 따른다. 따라서 CPU 코어수만 계속 늘리는 건 효율이 떨어진다.
Flynn's taxonomy)
이는 플린 분류라고 불리면 데이터 흐름을 고려해 병렬 컴퓨터 구조를 다음과 같이 분류했다.

SISD(Single Instruction stream Single Data stream)
- SISD는 현재 보통의 컴퓨터 구조이다.
- 명령 하나가 자료 하나를 처리하는 구조
- 제어장치가 한 개의 명령을 번역한 후 처리기를 작동시켜 명령을 처리할 때 기억장치에서 한 개의 자료를 꺼내서 처리
- Pipeline에 의한 시간적 병렬 처리가 가능하다.
SIMD(Single Instruction stream Multi Data stream)
- SIMD는 한 개의 명령으로 여러 Data를 동시에 처리
- 다수의 처리기가 한개의 제어장치 레 의해 제어된다. 즉 모든 처리기는 제어장치로부터 같은 명령을 수행하도록 제어하지만 처리기는 각각 다른 자료를 사용한다.
- 배열 처리기에 의한 동기적 병렬 처리가 가능하다.
MISD(Multi Instruction stream Single Data stream)
- MISD는 다수의 처리기에 의해 각각의 명령들이 하나의 Data를 처리하는 구조이다.
- MISD는 실제로는 사용되지 않는 구조
- Pipeline에 의한 비동기적 병렬 처리가 가능
- 검증을 위해 보통 3개가 동시 계산, 2개가 맞고 1개가 다르면 맞는 2개의 값을 참으로 인식
MIMD(Multi Instruction stream Multi Data stream)
- MIMD는 다수의 처리기가 각각 다른 명령 흐름과 자료 흐름을 가지고 여러 개의 자료를 처리
- 처리기들의 상호 연결 시 Tightly Coupled System을 다중 처리기, Loosely Coupled System을 분산 처리 시스템이라 한다.
MultiThreading Models)
스레드는 사용자 스레드와 커널 스레드가 존재한다.

- User thread : 커널의 도움 없이(syscall필요 x) 커널의 윗부분(User library)을 지원한다. 비교적 빠르고 효율적이나, 스레드 1개에 block이 생기면 모든 스레드가 block 된다. OS는 커널 스레드 기준으로 할당을 받기 때문에, 병렬적으로 안 돌아갈 수도 있다. POSIX Pthreads, Windows threads, Java threads
- kernel thread : OS에 직접적으로 지원 관리된다. syscall에 생성/관리가 이뤄진다. 각각의 스레드는 TCB를 필요로 한다. 여러 스레드를 멀티 코어에 돌릴 수 있다.
<Many to One>

사용자 스레드들이 하나의 커널 스레드와 연결되어있다. 그러나 만약에 syscall이 들어와서 스레드 하나가 block 되면 전체 프로세스가 block 된다. 다중 스레드들이 멀티코어 시스템에서 병렬적으로 작동하는 것이 불가능하다.
<One to One >

user 스레드가 각각 kernel 스레드와 연결되어 있다.
many to one의 문제점들을 대부분 해결했고 병렬적으로 실행 가능하다.
그러나 kernel 스레드가 많아질수록 시스템 성능이 떨어진다.
<Many to Many Model>

다대다 방식이지만 커널 스레드의 숫자가 유저 쓰레드 보다 적다.
위 두 가지 방법의 단점을 모두 해결할 수 있다.
필요한 만큼의 스레드들을 적당히 할당하여 사용 가능하다.
즉 커널 쓰레드들을 멀티 프로세서에서 병렬적으로 실행할 수 있다.
만약에 스레드가 block 되면 커널은 다른 스레드를 스케줄 해서 실행한다.

many to many 모델보다 구현하기 편하다.
최신 OS에서는 멀티 프로세서 시스템의 등장으로 대부분 one to one을 많이 사용한다고 한다.