-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++/ggjae #46
C++/ggjae #46
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,5 @@ | |
- 자바 API 활용 | ||
|
||
## C++ | ||
|
||
- [멀티스레드 프로그래밍](./c++/multithread-programming.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# Multithread Programming | ||
|
||
> 작성자 : [박재용](https://github.com/ggjae) | ||
|
||
본 자료는 작성자인 '박재용'의 개인 Repository의 글을 재구성하여 작성되었습니다. | ||
자료를 공부하기 이전에 익혀두어야 하는 두가지 기술을 먼저 이야기하겠습니다. | ||
|
||
- 프로세스와 스레드가 무엇인지 이해하기 | ||
- 스레드와 프로세스를 구분해보기 | ||
|
||
<details> | ||
<summary>Table of Contents</summary> | ||
|
||
- [프로세스 Review](#프로세스) | ||
- [스레드 Review](#스레드) | ||
- [멀티스레드 프로그래밍의 사용 이유](#멀티스레드-프로그래밍의-사용-이유) | ||
- [멀티스레드 프로그래밍이 힘든 이유](#멀티스레드-프로그래밍이-힘든-이유) | ||
- [병렬 프로그램](#병렬-프로그램) | ||
|
||
</details> | ||
|
||
--- | ||
|
||
## 프로세스 | ||
|
||
운영체제가 관리하는 프로그램의 단위 | ||
실행파일을 실행하는 것이 곧 프로세스를 만드는 것. 실행파일의 실행은 운영체제가 파일을 읽어서 메모리에 복사해두고 시작 주소로 점프하는 것. 멀티코어가 아니더라도 여러개의 프로그램이 동시에 실행된다. | ||
|
||
프로세스의 메모리 구조 | ||
|
||
- Code : 실행될 명령어가 들어가는 구역 | ||
- Data : 전역 변수가 들어가는 구역 | ||
- Stack : 지역변수와 함수 리턴 주소가 들어가는 구역 | ||
- Heap : malloc이나 New로 할당받은 메모리가 들어가는 구역 | ||
- PCB : Process Control Block | ||
|
||
프로세스는 내부적으로 성격에 따라 여러개의 구역으로 나누어서 관리를 하는 것을 **세그먼트**라 한다. | ||
|
||
## 스레드 | ||
|
||
프로그램 내에서의 실행되는 흐름의 단위 | ||
프로세스의 부분집합이다. 모든 스레드는 자신 고유의 스택을 가지고 있고 Data, Heap, Code 영역은 다른 스레드와 공유하게 된다. | ||
|
||
한 프로그램에서의 여러개의 스레드를 사용한다면 코드와 데이터 힙 영역은 스레드간 공유가 된다. 똑같은 메모리를 같이 사용하고 한 장소에 있는 것을 자식과 부모가 같이 사용한다고 생각하면 된다. | ||
|
||
--- | ||
|
||
## 프로세스와 스레드 관련 | ||
|
||
- 스택영역만 새로 하나 파주면 되기 때문에 스레드는 생성 시 overhead가 프로세스보다 작다. | ||
- 캐시 미스가 비교적 적게 일어나기 때문에 스레드는 Context Switching 비용의 overhead가 프로세스보다 적다. | ||
- 스레드간의 통신이 프로세스간의 통신보다 간단하다. 프로세스간의 통신은 overhead가 큼 | ||
- 하나의 스레드에서 발생한 문제가 전체 프로세스를 멈추게 한다. | ||
- 하나의 프로그램에서 여러군데가 동시에 실행되므로 스레드의 경우 디버깅이 너무나도 어렵다. | ||
|
||
|
||
# 멀티스레드 프로그래밍의 사용 이유 | ||
|
||
- 멀티코어 CPU에서의 프로그램 성능 향상을 위하여 | ||
- 멀티 CPU 컴퓨터, 병렬컴퓨터에서의 프로그램 성능 향상을 위하여 | ||
|
||
|
||
하나의 프로그램을 더 빠르게 돌리기 위해서 사용한다. | ||
10 FPS 게임을 20 FPS로 올리고 싶을 때, 처리량을 높이기 위하여 **멀티스레드** 프로그래밍을 한다. | ||
|
||
|
||
## 멀티스레드 프로그래밍이 뭐야? | ||
|
||
- 병렬 프로그래밍의 유일한 구현 수단 | ||
- 하나의 프로세스 안에서 여러개의 스레드를 실행시켜 병렬성을 얻는 프로그래밍 방법 | ||
|
||
|
||
## 성능을 위하여 멀티스레드 프로그래밍을 하는가? | ||
|
||
정답은 아니다. 게임은 성능이 중요하기 때문에 상관은 있지만 게임이 느리거나, 프로그램이 느리다면 성능 개선이 우선시 되어야 한다. 다양한 자료구조와 알고리즘을 통해서 성능개선을 진행해야 하고 최후의 보루로 멀티스레드 프로그래밍을 진행하여야 한다. | ||
**주의** 멀티스레드 프로그래밍을 하면 더 느려질지도 모른다. | ||
Comment on lines
+73
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 멀티스레드 프로그래밍을 하면 더 느려지는 이유는 무엇인가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사용하는 스레드가 많아지면 많아질수록 bottleneck의 가능성과, 쓰레드마다 참조하는 캐시가 다르므로 불일치 문제가 생기거나, 스레드 하나만으로도 진행할 수 있는 간단한 코드를 여러 스레드로 진행시켜도 race condition을 기다리기 위해 시간이 사용되거나 합니다! 적재적소에 사용하여야 하는 것이지요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 !! 그래서 프로그램 성능 개선이 우선된 후, 멀티 스레드 프로그래밍은 다양한 위험성을 고려하여 적절하게 사용해야하는 것이군요. 이해했습니다 ! 감사합니다 ㅎㅎ |
||
|
||
## 멀티스레드 프로그래밍이 힘든 이유 | ||
|
||
매번 같은 코드를 실행함에도 결과값이 달라진다. 우리가 프로그래밍해서 잘못된 결과면 계속 같은 잘못된 결과가 나와야 하는데 멀티스레드 프로그래밍은 값이 매번 다르다. 이것은 잘못 만든 프로그램으로 디버깅이 쉽지 않고 Data Race에 부딪힐 수 있다. | ||
Data Race란 같은 데이터를 두개의 스레드가 동시에 읽고 쓰고 할 때에 모든 전역 변수는 공유 메모리이므로 읽고 쓰는 순서에 따라 실행 결과가 달라지고 이 상태를 경쟁 상태라고 한다. 하지만 C++11에서 lock과 unlock을 지원해주므로 복수개의 스레드가 동시에 접근할 수 없도록 코딩을 진행하여야 한다. | ||
|
||
``` CPP | ||
#include <thread> | ||
#include <iostream> | ||
#include <mutex> | ||
|
||
std::mutex mtx_lock; | ||
|
||
int main(){ | ||
|
||
std::thread Threads1([&] (){ | ||
for(int i=0;i<5;++i){ | ||
mtx_lock.lock(); | ||
std::cout << "Thread Num : " << i << std::endl; | ||
mtx_lock.unlock(); | ||
} | ||
}); | ||
|
||
std::thread Threads2; | ||
Threads2 = std::thread([&](){ | ||
for(int i=10;i<15;++i){ | ||
mtx_lock.lock(); | ||
std::cout << "Thread Num : " << i << std::endl; | ||
mtx_lock.unlock(); | ||
} | ||
} | ||
return 0; | ||
} | ||
``` | ||
|
||
멀티스레드 프로그래밍 시 mutex 객체는 전역 변수로 코딩하여야 하고 같은 객체 사이에서만 lock과 unlock이 동작하는 것을 주의하여야 한다. 서로 동시에 실행되어도 괜찮은 Critical Section (lot reader, 0 writer)에서는 다른 mutex 객체로 보호하는것이 성능에 좋다. | ||
|
||
## 멀티코어 CPU | ||
|
||
**한 개 이상의 코어**로 구성된 CPU. i3, i5, i7 | ||
2021년 현재는 모든 것이 다 멀티코어 ex) Xbox, 닌텐도 스위치 | ||
|
||
|
||
## C++ 언어에 멀티스레드 라이브러리가 표준으로 존재 | ||
|
||
과거의 멀티스레드 프로그래밍 방법: | ||
Window에서는 Win32 라이브러리에서 지원되는 API 사용했었고, 윈도우는 멀티스레드에 특화된 OS이고 리눅스는 pthread API를 사용하면 가능했다. | ||
|
||
Windows에서의 thread => | ||
프로세스의 하위 개념 프로세스는 처음 시작 시 한개의 스레드를 갖고 시작되고 운영체제가 직접 스케쥴링하게 된다. | ||
|
||
--- | ||
|
||
## 병렬 프로그램 | ||
|
||
병렬 프로그램의 특징 | ||
- 실행된 프로세스 내부의 여러곳이 동시에 실행된다. | ||
- 병렬로 실행되는 객체 사이의 동기화가 필수이다. (synchronization) | ||
- **공유메모리 모델**과 메세지패싱 모델이 있다. | ||
|
||
## 병렬 프로그램의 요구사항 | ||
|
||
- 정확성 : 다양한 흐름에서 동시다발적으로 호출해도 문제 없이 실행되는 알고리즘이 필요 | ||
- 성능 : Context 증가에 따른 성능 향상이 높아야 함 | ||
|
||
--- | ||
|
||
### 자주 묻는 질문 | ||
|
||
1. **멀티코어 프로세서**를 만드는 이유? | ||
|
||
> CPU의 성능을 올려야하고, 클럭 속도를 높여야 한다. 하지만 클럭 속도를 높일 수 없음. 한계가 정해져 있다. => 클럭 속도가 4GHz가 되면 컴퓨터가 불에 타게 된다. 우주가 그렇게 설계되어 있음. | ||
4Ghz의 벽이라고도 한다. 사용하려면 실시간으로 액체질소를 들이부어야 함. 남은 것은 멀티코어 뿐이였고, 싱글로는 도저히 안되니까 코어 개수로 싸우고 있다. 듀얼코어 CPU 2개, 쿼드코어 CPU 1개 차이는 크지 않다. 여러 코어가 늦게 개발된 이유는 프로그램을 다시 짜야하는 번거로움뿐만 아니라 디버깅도 어렵고 이미 작성한 알고리즘도 사용하지 못하기 때문이다. | ||
|
||
2. 스레드의 개수와 코어의 개수는 일치하지 않아도 상관이 없는 이유? | ||
|
||
> 프로세스가 시분할로 돌아가면서 실행되듯 스레드도 시분할로 운영되어 중간에 다른 스레드가 실행될 수 있다. 쉽게 코어의 개수는 CPU 내 물리적 연산부의 개수이고, 스레드는 **작업단위**이므로 일치하지 않아도 된다. | ||
|
||
3. 멀티스레드 프로그래밍을 진행했을 때 싱글스레드 프로그래밍보다 느려졌다. 그 이유는 무엇일까? | ||
> 사용하는 스레드가 많아지면 많아질수록 bottleneck의 가능성과 쓰레드마다 참조하는 캐시가 다르므로 불일치 문제가 생기거나 스레드 하나만으로도 진행할 수 있는 간단한 코드를 여러 스레드로 진행시켜도 race condition을 기다리기 위해 시간이 사용되곤 한다. 적재적소에 사용하여야 한다. | ||
Comment on lines
+155
to
+156
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😆 😆 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
멀티 코어가 아니더라도 여러 개의 프로그램이 동시에 실행된다 -> 멀티 코어가 아닐 경우 시분할, 스케줄링 등을 통해 실제로는 동시에 실행되지 않지만 동시에 실행되는 것처럼 보이도록 한다고 알고 있는데 혹시 맞나용 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇죠. 단일 CPU에서 실행되는 것은 하나의 명령어로 한 프로그램이지만, '시분할' 을 통해서 시간을 잘게 분할하여 여러 응용프로그램이 돌아가는 것 처럼 보이고, '멀티태스킹'이란 기술로 여러개가 동시에 실행되는 것 처럼 보이게 만들죠.
제가 말한 '멀티코어가 아니더라도 여러개의 프로그램이 동시에 실행된다는 것'은 메모리에 적재되어 있는 프로세스들이 진행되고 있음을 이야기합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 이해했습니다 !!
'멀티태스킹'에 대해서도 정확히 찾아보니 하나의 CPU가 여러 프로세스를 스케줄링을 통해 마치 동시에 실행하는 것과 같은 환경을 제공하는 것을 말하네요. 아래 자료에서 말하는 '멀티프로세서'는 멀티 코어를 말하는 걸까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음.. 제 생각에는 '다수의 CPU를 내장한 컴퓨터'라서 이 문맥에서의 '멀티프로세서'는 CPU가 2개 이상인 컴퓨터를 뜻한다고 생각합니다. 멀티 코어라함은 한 CPU가 여러개의 코어를 가지고 있는것을 이야기하구요. 아마 여기서는 '코어'의 개념보다는 한 CPU에서 여러 멀티태스킹이 진행되고, 여러 CPU에서는 여러개와 여러개가 합친 멀티태스킹이 가능하다고 설명하는 것 같아요 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 이해했습니다 ! 멀티프로세서랑 멀티코어의 차이점도 알게되었네요 !! 자세한 설명 감사합니다 잘 기억해두겠습니다 ㅎㅎ !!