Concurrency와 Parallelism은 헷갈리기 쉬운 개념입니다. 이름도 Concurrency(동시성)과 Parallelism(병렬성)으로 이름만 들었을 때는 이 둘의 차이를 구분하기 어렵습니다. Concurrency와 Parallelism의 특징을 정리하면 다음과 같습니다.
Concurrency (동시성) | Parallelism (병렬성) |
동시에 실행되는 것처럼 보이는 것 | 실제로 동시에 실행되는 것 |
논리적인 개념 | 물리적인 개념 |
싱글코어, 멀티코어에서 가능 | 멀티코어에서만 가능 |
표만 봤을 때는 내용이 잘 와닿지 않습니다. Concurrency와 같은 경우 "동시에 실행되는 것처럼 보이는 것은 뭐지?"라는 생각이 들 수 있습니다. 그림과 함께 그리고 동기화 관점에서 Concurrency가 왜 동시에 실행되는 것처럼 보이는 것인지 정리해보려 합니다.
Parallelism
Parallelism은 여러 코어에서 여러 작업을 동시에 수행하는 것입니다. 코어가 하나밖에 없다면 병렬적으로 프로그램을 실행할 수 없습니다.
CPU는 single core의 성능을 올리는 데 한계를 느끼고 multi-core 체제로 넘어갔습니다. 여러 코어에서 여러 작업을 동시에 수행하면서 성능을 올리려 한 것입니다.
하나의 코어에서 하던 작업을 세 개의 코어에서 나누어 하니 이론적으로는 성능이 3배까지 좋아질 수 있습니다. 모든 작업을 병렬적으로 수행하기는 어려우니 3배의 성능 향상을 기대하긴 어렵지만 기존 보다는 성능이 향상될 것입니다. 하지만 여러 작업을 동시에 수행하니 race condition 혹은 동기화 문제가 발생할 수 있습니다.
Concurrency
Concurrency는 빠르게 전환하며 여러 작업을 수행하여 동시에 여러 작업이 실행되는 것처럼 보이는 것입니다. 한 개의 코어에서도 여러 작업을 Concurrent하게 실행할 수 있고 작업 간에는 context switch가 일어납니다.
Concurrent하게 실행되는 Task들은 운영체제의 스케줄링 정책에 의해 실행되며 서로 복잡하게 엉켜있습니다. 이들이 어떻게 엉켜있는지 생각하는 건 어려우니 동시에 실행된다고 생각하는 게 Concurrency 입니다. 그렇기 때문에 Task가 동시에 수행될 때 생길 수 있는 문제점, 대표적으로 동기화 문제가 발생할 수 있습니다.
동기화 문제는 Concurrent한 Task 사이에서 발생한다
동기화 문제는 여러 작업이 동시에 공유된 자원에 접근하려 할 때 발생합니다. 동시에라는 말 때문에 멀티코어에서만 발생할 것 같지만 한 코어에서 concurrent하게 동작하는 task 사이에서도 동기화 문제가 발생합니다.
한 코어에서 실행되는 Task1과 Task2가 동시에 공유자원인 data에 접근하려 합니다.
원래대로 라면 data에 1을 더하고 다시 1을 뺐으니 작업이 끝난 후 data에 100이 들어가 있어야 합니다. 하지만 동기화 문제가 발생하면 data에 99나 101이 들어있을 수 있습니다.
Task1이 data에 100을 읽어 1을 더하고 있는 사이(1) Task2에서도 data를 읽어(1') 갑니다. 이 때는 아직 Task1이 data를 101로 업데이트 하기 전이기 때문에 Task2도 100이라는 값을 읽게 됩니다. Task1은 data += 1을 실행(2)하고 data를 101로 업데이트(3) 합니다. Task2는 data를 100으로 읽었으므로 100에서 1을 뺀(2') 99로 data 값을 업데이트(3') 합니다. 동기화 문제가 발생하면 예상되는 결과와 다른 결과가 생길 수 있습니다. 이렇듯 Concurrent Task 사이에는 동기화 문제가 발생할 수 있기 때문에 이를 막기 위한 동기화 기법을 사용해주어야 합니다.