Announcement

이번 블로그 포스팅은 배운 내용을 정리해보려 합니다. 잘못된 부분이 있을 경우 코멘트 부탁드립니다. 정정 코멘트 환영합니다!

Intro

멀티 스레드 프로그래밍은 개발자의 숙명입니다. CPU 클럭 상승의 한계로 인하여 하나의 칩에 2개 의상의 코어를 결합하는 멀티 코어로 발전해가고 있습니다. 4코어는 기본이고, 16코어 이상의 모델도 하이엔드 제품군에서 흔하게 등장합니다. 그렇기에 소프트웨어 또한 이런 물리적 환경에 맞춰 이점을 최대한 살리도록 개발되어야 합니다.

그렇지 않으면 이처럼 될 수 있습니다.
(* 현재 월드 오브 탱크는 멀티 코어를 지원하며 위와 같은 모습은 다시 나타나지 않고 있습니다.)

하지만 멀티 스레드 프로그래밍 중에는 많은 문제에 봉착할 수 있습니다. 가장 대표적인 문제는 공유 리소스 접근입니다. 힙(heap)에 저장된 변동될 수 있는(mutable) 공유 리소스를 여러 스레드에서 활용할 경우, 경합을 방지하고 한 번에 한 개의 스레드에서만 활용하도록 lock과 같은 제약을 사용해 임계 구역(critical section)을 만듭니다.

하지만 lock을 사용하는 순간부터 개발자는 여러 상황을 생각해야 합니다. lock이 빠진 곳은 없는지, 교착 상태(deadlock), 기아 상태(starvation)는 발생하지 않는지. 또, 암달의 법칙에 의한 성능 향상 한계점도 고려해야 합니다.

Amdahl's law

병렬 컴퓨팅에서 멀티 프로세서를 사용할 때 프로그램의 성능향상은 프로그램의 순차적인 부분에 의해 제한된다. 예를 들면, 프로그램의 95%가 병렬화할 수 있다면 이론적인 최대 성능 향상은 아무리 많은 프로세서를 사용하더라도 최대 20배로 제한됩니다.
출처: ko.wikipedia.org/wiki/암달의 법칙

이런 식으로 여러 상황을 최대한 고려해서 설계하더라도, 산업 현장에서 프로세서의 수가 64코어, 128코어를 넘어가고 클라우드 환경에서 스케일-아웃으로 확장할 경우 수 천 개가 넘어가는 프로세서에서는 더욱이 예측 불가능한 상황이 나타나기 마련입니다.

이러한 대부분 문제는, 변경 가능한 공유 상태(Shared mutable state)에서 옵니다. 예를 들어, 기본적으로 Mutable한 객체를 생성하는 Java, C#이나 포인터 접근이 쉬운 C, C++에서는 실수하기도 쉬울뿐더러 힙에 저장된 리소스가 누가 언제 어떻게 변화시키는지 전부 예측하고 관리하기는 정말 어렵습니다.

이를 타개할 방법으로 액터 모델(Actor model)이 있습니다. 사실 액터 개념은 44년 전 1974년에 칼 휴이트(Carl Hewitt)라는 사람이 제안했습니다. 그리고 얼랭(Erlang)은 이 액터 모델의 패러다임을 가지고 태어났습니다.

액터 모델(Actor Model)

액터 모델은 “모든 것은 액터다(Everything is an actor)”라는 기본 철학을 가지고 갑니다. OOP에서의 “모든 것은 객체다(Everything is an object)”라는 철학과 비슷하지만, 객체 지향 소프트웨어는 기본적으로 순차적 실행을 하지만 액터 모델은 본질적으로 동시성을 제공하는 점이 다릅니다.
그러면 액터(Actor)란 무엇이냐 라는 질문이 나올 수 있습니다. 액터는 비동기적으로 메세지를 처리할 수 있는 computational entity로 다음과 같은 특징이 있습니다:

  • 다른 액터에게 유한한 개수의 메세지를 보낼 수 있습니다.
  • 유한한 개수의 새로운 액터를 만들 수 있습니다.
  • 다른 액터가 받을 메세지에 수반될 행동(behavior)을 지정할 수 있습니다.

실제 사람과의 커뮤니케이션을 상상하면 좀 더 이해하기 편합니다. 사람들은 초능력이 존재하지 않기에 타인과 머릿속 생각을 직접 공유하지 못하고, 대화(message)를 통해 대화를 주고받습니다.
액터 또한 똑같습니다. 메세지를 주고받아 다른 액터와 상호작용을 합니다. 액터가 차지하는 메모리 공간은 독립적이며, 다른 스레드나 액터가 접근할 수 없습니다. 다시 말하면, 메모리 공유 없이 메세지 전달만을 사용하기에 공유 메모리로 인한 교착 상태 등의 골치 아픈 상황들을 피할 수 있습니다.

Amdahl's law

이러한 액터 모델을 구현한 라이브러리 중에서 대표적으로 Akka가 있습니다. Akka는 JVM 상에서 동작하며 JAVA와 Scala 언어를 사용하는 고도의 동시(concurrent) 및 분산(distributed) 응용 프로그램을 빌드하기 위한 툴킷 및 런타임입니다. 또한 Akka.NET에 액터 모델에 대한 기초부터 스스로 배울 수 있도록 좋은 강의를 배포하고 있습니다. 그 강의를 이수하며 배운 내용을 주제로 포스트를 작성 해보겠습니다.

다음 포스트: Akka 공부하기 - 01.액터(Actors)와 액터시스템(ActorSystem)

Reference