IT/컴퓨터구조

🖥️ [컴퓨터구조] 병렬성과 동기화 문제

BlogFlow 2025. 3. 1. 18:00
반응형

[컴퓨터구조 목차 바로가기]

2️⃣ 명령어와 컴퓨터 언어

컴퓨터의 성능을 향상시키는 주요 방법 중 하나는 병렬 처리(Parallel Processing) 를 활용하는 것입니다.

멀티코어 CPU, 멀티스레드 프로그래밍, 분산 시스템에서는 여러 개의 작업을 동시에 수행하여 성능을 극대화할 수 있습니다.

그러나, 병렬 처리에는 동기화(Synchronization) 문제, 데이터 경쟁(Race Condition), 교착 상태(Deadlock) 등의 복잡한 문제가 발생할 수 있습니다.

이번 섹션에서는 병렬 처리의 개념, 동기화 문제의 원인과 해결 방법, 그리고 실제 사례에서의 적용 방법을 자세히 살펴보겠습니다.


🔹 1. 병렬성(Parallelism)이란?

1.1 병렬 처리(Parallel Processing)의 개념

병렬 처리란 여러 개의 프로세서 또는 스레드가 동시에 연산을 수행하는 방식을 의미합니다.

병렬 처리의 목적:

  • 연산 속도 향상 → 더 많은 작업을 짧은 시간에 처리
  • 시스템 자원 활용 극대화 → CPU 코어, GPU, 분산 시스템 활용
  • 대규모 데이터 처리 → AI, 과학 연산, 시뮬레이션 등에 필수

💡 병렬 처리는 CPU의 여러 코어가 동시에 연산을 수행하는 방식!


1.2 병렬 처리의 종류

병렬 처리는 하드웨어 구조 및 실행 방식에 따라 여러 유형으로 나뉩니다.

병렬 처리 모델 설명 예제
SISD (단일 명령어, 단일 데이터) 전통적인 순차적 실행 방식 일반적인 싱글코어 CPU
SIMD (단일 명령어, 다중 데이터) 동일한 연산을 여러 데이터에 수행 벡터 연산, AVX, GPU
MISD (다중 명령어, 단일 데이터) 하나의 데이터를 여러 방식으로 처리 신경망, 파이프라인
MIMD (다중 명령어, 다중 데이터) 여러 연산이 동시에 실행 멀티코어 CPU, 클러스터 컴퓨팅

💡 실제 사례:

  • SIMD (Single Instruction, Multiple Data) → 그래픽 처리, AI 연산
  • MIMD (Multiple Instruction, Multiple Data) → 멀티코어 프로세서, 데이터센터

🔹 2. 병렬 처리의 문제점 (동기화 문제)

2.1 동기화(Synchronization) 문제란?

병렬 처리는 여러 개의 프로세스 또는 스레드가 동시에 같은 자원(데이터)에 접근할 때 문제가 발생할 수 있습니다.

이러한 문제를 해결하지 않으면 데이터 불일치, 성능 저하, 예측 불가능한 결과가 발생할 수 있습니다.

문제 유형 설명
경쟁 조건(Race Condition) 두 개 이상의 스레드가 동일한 데이터를 동시에 수정하려 할 때 발생
데이터 일관성(Data Consistency) 문제 여러 스레드가 공유 데이터를 다룰 때 값이 엉킬 수 있음
교착 상태(Deadlock) 여러 프로세스가 서로 자원을 기다리면서 영원히 멈추는 상태
기아 상태(Starvation) 특정 프로세스가 계속해서 CPU 자원을 할당받지 못하는 문제

💡 쉽게 말해:

  • 여러 개의 스레드가 동시에 같은 데이터를 수정하면 데이터가 엉킬 수 있음!
  • 동기화 기법을 적용해야 문제를 해결할 수 있음!

2.2 동기화 문제의 실제 예제

예제: 경쟁 조건 (Race Condition)

💡 두 개의 스레드가 동일한 변수(count)를 증가시키는 코드

int count = 0;

void thread1() {
    count = count + 1;  // count 값을 증가
}

void thread2() {
    count = count + 1;  // 동시에 count 값을 증가
}

문제:

  • count 값이 1 증가해야 하지만,
  • 두 개의 스레드가 동시에 접근하면 예상치 못한 결과가 발생할 수 있음.

💡 해결 방법:

  • 뮤텍스(Mutex), 세마포어(Semaphore), 원자적 연산(Atomic Operation) 등을 사용하여 동기화 필요

🔹 3. 동기화(Synchronization) 기법

동기화 문제를 해결하기 위해 다음과 같은 기법이 사용됩니다.

3.1 락(Lock) 기반 동기화

🔹 1) 뮤텍스(Mutex, Mutual Exclusion)

  • 하나의 스레드만 공유 자원에 접근할 수 있도록 락(Lock)을 설정
  • 락을 획득한 스레드만 연산을 수행할 수 있음

💡 뮤텍스 예제 (C - Pthread)

pthread_mutex_t lock;
int count = 0;

void* thread_function(void* arg) {
    pthread_mutex_lock(&lock);  // 락 획득
    count++;
    pthread_mutex_unlock(&lock);  // 락 해제
}

장점: 데이터 충돌 방지 가능

단점: 성능 저하(락을 획득하는 동안 다른 스레드는 대기)


🔹 2) 세마포어(Semaphore)

  • 여러 개의 스레드가 동시에 접근할 수 있도록 제한하는 방식
  • 데이터베이스, 네트워크 서버 등에서 많이 사용됨

💡 세마포어 예제 (C - Pthread)

sem_t semaphore;
sem_wait(&semaphore);  // 접근 시도
count++;
sem_post(&semaphore);  // 접근 해제

장점: 뮤텍스보다 더 유연한 접근 방식 제공

단점: 복잡한 관리가 필요


3.2 원자적 연산(Atomic Operations)

  • CPU가 하드웨어적으로 락을 사용하지 않고 동기화할 수 있도록 지원
  • CPU 명령어 자체가 원자적(Atomic)으로 실행됨

💡 원자적 연산 예제 (C - GCC Built-in Function)

__sync_fetch_and_add(&count, 1);  // count 값을 원자적으로 증가

장점: 락 없이 빠른 동기화 가능

단점: 모든 연산을 원자적으로 수행할 수 없음


3.3 교착 상태(Deadlock) 해결 방법

교착 상태(Deadlock)가 발생하면 두 개 이상의 스레드가 서로 자원을 점유한 채 무한 대기하는 상태가 됩니다.

이를 방지하기 위한 기법은 다음과 같습니다.

해결 방법 설명
자원 할당 순서(Resource Ordering) 자원을 항상 동일한 순서로 할당
타임아웃 설정(Timeouts) 일정 시간 후에 락을 해제
교착 상태 탐지(Deadlock Detection) 주기적으로 교착 상태를 감지하여 해결

✅ 마무리: 병렬성과 동기화 문제의 핵심

병렬 처리는 성능을 극대화하지만, 동기화 문제가 발생할 수 있음

경쟁 조건(Race Condition), 데이터 불일치 문제 해결 필요

뮤텍스(Mutex), 세마포어(Semaphore), 원자적 연산(Atomic)으로 동기화 문제 해결 가능

교착 상태(Deadlock) 발생 방지를 위한 전략 필요


반응형