동시성과 병렬성

낚시하는 곰·2025년 4월 1일

krafton jungle

목록 보기
34/52

동시성과 병렬성이란?

개념설명
동시성 (Concurrency)여러 작업이 동시에 진행되는 것처럼 보이게 만드는 것 (실제로는 하나씩 번갈아가며 처리)
병렬성 (Parallelism)여러 작업이 물리적으로 동시에 수행되는 것 (멀티코어 CPU에서 실제 병렬 실행)

flow

[ 프로그램 실행 ]
        ↓
 [ 여러 작업이 필요 ]
        ↓
 ┌────────────┬────────────┐
 │ 동시성     │ 병렬성     │
 │ (논리적 동시에)│ (물리적 동시에)│
 └────────────┴────────────┘
        ↓
 [ 공통적으로 쓰레드, 스케줄러, 버퍼 등 활용 ]
        ↓
 [ 성능 향상 및 응답성 개선 ]

동시성과 병렬성의 속도 차이는 얼마나 될까?

항목동시성병렬성
코어 수1개2개 이상
실행 방식빠른 전환(context switching)진짜 동시에 실행
속도느릴 수 있음 (전환 오버헤드 존재)더 빠름 (작업 분산)

실행 속도 차이에 영향을 주는 요소

  1. 작업의 성격 (CPU-bound vs I/O-bound)

    • CPU-bound 작업: 수치 계산, 영상 처리 등 CPU 자원을 많이 먹는 작업이면 병렬성이 훨씬 빠름.
    • I/O-bound 작업: 파일 읽기, 네트워크 요청처럼 대기 시간이 많은 작업은 동시성도 충분히 빠를 수 있음.
  2. context switching 오버헤드

    • 동시성은 매번 작업을 바꿔줄 때 레지스터, 스택, 캐시 상태를 저장하고 복원해야 해 → 시간이 꽤 듦.
    • 병렬성은 코어별로 작업이 나뉘므로 그런 오버헤드가 거의 없음.
  3. 캐시 활용

    • 병렬성은 잘 설계하면 각 코어가 L1/L2 캐시를 효율적으로 써서 성능 상승 가능.
    • 하지만 잘못 설계하면 캐시 일관성(Coherency) 문제도 발생.

예시

  • 작업 수: 4개, 각 작업이 CPU 연산으로 10초 소요.
  • 단일 코어 (동시성):
    • context switching 비용 감안하여 총 42초 걸릴 수 있음.
  • 4코어 병렬 처리:
    • 각 작업이 독립적으로 실행 → 10초 이내에 끝날 수 있음.

즉, 병렬성은 상황에 따라 2배 ~ 10배 이상의 속도 차이를 만들 수 있어.


추상화가 뭘까?

추상화란, 복잡한 시스템 내부 구현을 감추고, 사용자(혹은 개발자)가 간단한 인터페이스로만 다룰 수 있게 하는 것.

예:

  • 우리는 스레드를 직접 스케줄링하지 않아도 Thread.start() 한 줄로 시작 가능.
  • 운영체제는 우리가 직접 코어 스케줄을 짜지 않아도 알아서 처리해 줘.

병렬성과 추상화의 관계

관계 요소설명
병렬성은 복잡함여러 스레드가 공유 자원을 다루면, 동기화 문제·데드락·레이스 컨디션 등 복잡성이 폭발해.
추상화는 복잡성을 숨겨줌병렬 시스템의 내부 구조를 감추고, 개발자가 쉽게 병렬 처리를 할 수 있도록 도와줘.
추상화가 병렬성 도입을 쉽게 해줌병렬 처리의 성능 이점을 누리되, 프로그래머가 직접 모든 걸 관리하지 않게 해 줘.

예시로 보는 관계

병렬성 기술추상화 계층설명
pthread낮은 추상화개발자가 직접 락, 동기화, 스케줄링 제어
Java ExecutorService, Python concurrent.futures중간 추상화스레드 풀, 큐 등을 프레임워크가 관리
GPU 병렬 처리 (e.g. CUDA)높은 추상화 도구 필요쓰레드 수 천 개를 관리하는 건 복잡하므로, 추상화가 필수
MapReduce / Spark아주 높은 추상화병렬성을 거의 느끼지 않고 데이터 처리 가능

요약하면

병렬성은 성능 향상을 가능하게 해주지만, 복잡성을 동반한다.
추상화는 이 복잡성을 감추고, 병렬성을 쉽게 활용할 수 있도록 만들어주는 수단이다.


추상화가 너무 강할 때 생기는 문제

문제설명
세밀한 스레드 제어 불가스레드 수, 바인딩, 스케줄링 우선순위 등을 튜닝할 수 없으면 성능 최적화가 어려워져.
자원 할당의 비효율내부 구현을 숨기면, CPU 코어나 메모리 사용이 비효율적으로 돌아가도 알아채기 어려움.
병목 지점 분석 어려움병렬 처리 중 어느 부분에서 병목이 생기는지 파악이 힘듦.
병렬성 숨긴 구조로 인해 불필요한 동기화 비용 발생추상화된 내부에서 락을 너무 과도하게 쓰면 오히려 병렬성이 병목이 되기도 해.

예를 들어서 보면:

  • MapReduceSpark 같은 고수준 추상화 프레임워크는 병렬 처리를 정말 쉽게 해줘.
    • 하지만 특정 연산에서 "이 노드는 더 강한 서버야, 여기에 더 많은 작업을 줘야 해!" 같은 세부 최적화는 어려움.
  • 반대로 OpenMP, CUDA, pthread 같은 로우레벨은 복잡하지만 성능 튜닝 가능.

그래서 현실은?

병렬성 추상화는 항상 "균형" 이 중요해.
너무 낮으면 복잡하고, 너무 높으면 비효율적이야.

대부분의 프레임워크는 이 균형을 위해:

  • 기본 설정은 쉬움 (초보자용)
  • 고급 옵션은 세세하게 제어 가능 (전문가용)

profile
취업 준비생 낚곰입니다!! 반갑습니다!!

0개의 댓글