동시성(Concurrency)와 병렬성(Parallelism)

OCaml이 멀티 코어를 통해 더 나은 지원을 하려 노력하는 두 가지 중요한 계산 방법이 있다.

  • 동시성(Concurrency)은 여러 계산을 분할해서 엄격하게 순차적으로 실행하는 되는 것이 아니라, 겹치는 시간(overlapping time)에 실행할 수 있도록 하는 방법이다. OCaml은 하나의 힙에 대해서는 이미 LwtAsync같은 훌륭한 라이브러리들이 있다. OCaml의 Thread 모듈 역시 동시성 계산을 표현하기 위한 훌륭한 방법이다.
  • 병렬성(Parallelism)은 여러 계산을, 주로 멀티코어 머신의 여러 개의 코어를 이용해서 동시에 실행하는 방법이다.

OCaml에는 동시성과 병렬성을 지원하는 여러 메커니즘들이 존재한다.

시스템 동시성 병렬성
OCaml 4.11 Thread 모듈 직접적인 스타일(Direct-style)의 코드를 동시에 실행할 수 있음, pthreads 사용 OCaml 런타임 락으로 인해, C 쓰레드가 병렬적으로 실행되긴 하지만 최종적으로는 하나의 OCaml 쓰레드로 합쳐짐
Lwt / Async 모나드 스타일(monadic interface)로 코드를 짜야 함 싱글 쓰레드이지만 입출력을 병렬로 할 수 있음
Functory map처럼 Functory 모듈 스타일로 동시성 연산을 짜야 함 여러 개의 런타임에서 동작하며, 분산 처리도 가능

이런 방법들은 여러 개의 코어에서 병렬적으로 OCaml 코드가 실행되는 직접적인 스타일의 동시성을 지원하지 않는다. 멀티코어 OCaml 프로젝트는 이러한 한계를 해결하고 직접적인 스타일로 작성된 OCaml 코드가 공유 메모리 병렬성(Shared-Memory Parallelism; SMP)을 허용하는 것을 목표로 한다.

도메인과 파이버, 이펙트

현재 멀티코어에서 동시성과 병렬성에 대한 추상화 구현체는 두 가지가 있다.

  • 도메인은 병렬적으로 실행되며, 자신만의 마이너 힙을 가지고 멀티코어 마이너/메이저 GC를 관리하는데 필요한 동기화가 필요하기 때문에 상당히 무겁다. domainslib 라이브러리를 사용하면 도메인을 이용해서 병렬 계산을 쉽게 할 수 있다.
  • (이펙트를 통해 제공되는) 파이버는 유연한 동시성을 허용하는 동적 스택을 갖고 있는 가벼운 실행 문맥이다. 파이버는 이펙트를 통해서 만들어지고 관리된다(scheduled). 도메인끼리 컨티뉴이에션을 주고 받을 수 있어서 멀티코어 런타임 위에서 복잡한 스케쥴링이 가능하다.

참조

  • 도메인은 블로킹 연산에 대해서는 블록된다. 구체적으로, 다른 계산의 스케쥴링이 멈춘다.
  • 블로킹 연산이 호출되면 도메인도 블록되기 때문에, 만약 파이버가 블로킹 C 연산을 호출하면 해당 도메인에서 수행되는 모든 스케쥴링은 이 연산이 끝날 때까지 블록된다.
  • 멀티코어 GC는 도메인 개수가 물리적 코어의 개수보다 작거나 같을 때 가장 잘 동작하도록 설계되었다. 런타임이 가비지 콜렉터를 관리하기 위해 도메인마다 추가적인 상태를 갖기 때문이다. 마이너 콜렉션과 메이저 싸이클의 끝에서 도메인들끼리 동기화가 필요하다. 그러므로, 도메인이 시스템 (p)쓰레드와 짝지어지긴 하지만, OCaml에서는 더 무거운 추상화로 취급된다.