개요
현재 CPU 코어의 성능이 좋아졌지만 CPU의 성능을 온전히 사용하기 위해서는 멀티 태스킹, 멀티 스레딩 등 프로그램의 최적화가 필요합니다.
특히 많은 연산이 필요한 서버 등의 경우 이러한 최적화가 중요합니다.
멀티프로세싱과 멀티태스킹을 헷갈리는 경우가 있는데 병렬적으로 여러 프로세서를 사용하는 것을 멀티프로세싱이라고 하고, 코어에서 여러 프로세스를 컨텍스트 스위칭을 통해 시분할로 처리하는 것을 멀티태스킹이라고 합니다.
멀티스레딩
멀티프로세싱은 프로세스를 전환하며 처리하는 것이지만, 멀티스레딩은 프로세스 안에 나눠진 스레드를 전환하며 처리하는 것입니다.
스레드는 하나의 작업 흐름으로 프로세스에서 뻗어진 갈래입니다.
스레드는 프로세스의 힙, 데이터 영역을 공유하기 때문에 (스택은 공유되지 않음) 컨텍스트 스위칭 시에 오버헤드가 프로세스를 전환하는 것에 비해 적습니다.
멀티스레딩 주의할 점
프로그램은 굉장히 빠른 속도로 스레드 실행 흐름을 전환하며 진행하기 때문에 문제가 생길 수 있습니다.
가장 쉬운 예시로 보면 위의 경우 0에서 10만번 더하고 10만번 뺐는데 출력해보면 답이 0이 나오지 않습니다.
sum++ 같은 연산은 high level 언어로 작성하면 한줄로 보이지만 실제로는 여러 줄의 low레벨 언어로 바뀝니다.
sum++과 sum--가 동시에 실행되는 경우
1.레지스터에 sum값을 불러옴
2.레지스터의 값을 증가,감소시킴
3.레지스터의 값을 메모리에 저장함
이 1, 2, 3단계가 섞일 수 있습니다.
결론적으로 Add, Sub를 실행시키면 값이 0, -1, 1 셋중하나가 나올 수 있다는 것입니다.
어떻게 해결?
락(lock)을 통해서 해결합니다. (atomic 한 연산)
해당 코드를 시작하기 전에 락을 acquire하고, 코드를 실행시킨 후 락을 release한다면 하나의 스레드가 lock을 획득 했을 때 다른 스레드들은 lock을 획득할 수 없기 때문에 해당 영역의 코드는 하나의 스레드만 실행하는 것을 보장할 수 있다.
lock 획득 자체는 atomic한 연산으로 CPU에서 흐름이 섞일 걱정을 하지 않아도 된다.
그건 알겠는데 어떻게 구현?
c++ 기준으로 atomic, mutex, lock_guard 등을 사용하는데 다른 포스트에서 알아보자그요
'CS > 멀티쓰레딩' 카테고리의 다른 글
Compare And Swap(CAS) 아주 간단하게 훑기 (0) | 2025.03.11 |
---|---|
스레드 경합 해결하기(lock) -1 (0) | 2025.03.06 |