[게임 서버] 1.9 병렬성과 시리얼 병목
카테고리: GameServer
태그: GameServer
이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
게임 서버 프로그래밍 교과서, 배현직 저자
📦 1. 멀티스레딩
👉🏻 9. 병렬성과 시리얼 병목
뮤텍스가 보호하는 영역이 너무 넓으면, 싱글스레딩과 다를 게 없다.
- 병렬성 (parallelism): 여러 CPU가 각 스레드의 작업을 동시에 처리함
- 시리얼 병목 (serial bottleneck): 병렬성이 안 나오고, 특정 부분이 병목이 되어 CPU 하나만 일하는 상황
🔢 예시: 소수 구하기 프로그램
소수 구하기 프로그램에서 스레드가 하는 일을 간략히 나타내면 다음과 같다:
1번 | 2번 | 3번 |
---|---|---|
lock(num) n = num num++ unlock(num) |
IsPrimeNumber(n) | lock(primes) primes.add(n) unlock(primes) |
여기서 1번과 3번은 뮤텍스를 사용하므로 동시에 실행 불가.
결국, 병렬성은 2번 (소수 판별) 부분에서만 나오게 된다.
💻 CPU가 놀고 있는 상황
극단적인 경우, CPU는 병렬 처리를 해도 다음과 같이 빈 구간이 생긴다:
CPU / 순서 | 1번 | 2번 | 3번 |
---|---|---|---|
CPU 0 | idle! | IsPrimeNumber(n) | idle! |
CPU 1 | idle! | IsPrimeNumber(n) | idle! |
… | idle! | IsPrimeNumber(n) | idle! |
CPU n | lock(num)n = num num++ unlock(num) |
IsPrimeNumber(n) | lock(primes) primes.add(n) unlock(primes) |
결국 2번을 제외하면, 다른 CPU는 쉴 수밖에 없다.
📐 암달의 법칙 (Amdahl’s Law)
시리얼 병목이 있는 상황에선, CPU 개수를 늘려도 처리 속도가 그만큼 올라가지 않는다.
→ 병렬로 처리 가능한 부분이 전체 연산에서 차지하는 비율이 중요
🧪 Visual Studio로 멀티스레딩 분석
1. 확장 설치
2. 프로그램 실행 후 프로세스 연결
3. 올바른 프로세스 선택
4. 분석 결과: 병목 없음
ThreadCount = 4
로 짰을 때, 실제 스레드 4개 동작 확인- CPU 사용률이 100%에 가까움
→ 병렬성이 잘 나왔고, 시리얼 병목 없음
5. 병목 상황 만들기: Sleep(1) 삽입
뮤텍스 잠금 영역에 Sleep(1)
을 넣고 다시 분석:
lock()
~unlock()
사이에 Sleep 발생- 대기 시간이 25% 수준으로 나타남
→ 시리얼 병목이 생겼다
⌛ 디바이스 타임과 CPU 타임
lock(A)
ReadFromDisk(X) // 디스크 접근 (디바이스 타임)
unlock(A)
ReadFromDisk
같은 디스크 접근은 디바이스 타임(device time) 발생
→ 이때 스레드는 sleep 상태가 됨- CPU 타임은 CPU가 실제로 연산을 수행한 시간
→ 클럭 틱 단위로 측정됨
🔗 디바이스 타임이 임계영역 안에 포함되면, 병렬 처리 효과가 떨어진다.
→ 이 역시 시리얼 병목의 원인이 된다.
댓글남기기