V8-isolate study

결국 독립적인 heap 메모리 할당, GC 등을 통하여 독립적인 실행 환경을 구성하도록 해준다.

https://github.com/nodejs/node/blob/main/src/node_worker.cc 위 파일에서 확인 시 Node.js의 worker_thread 또한 내부적으로 v8-isolate를 사용하여 구현된 것을 알 수 있는데, 그렇기에 동작이 매우 유사하다.

경량 스레드

경량 스레드는 (Light weight thread) 는 일반적인 스레드와 달리 운영체제 커널에서 관리되지 않고 유저 레벨에서 관리되는 스레드이다. 효율적인 멀티스레딩 환경을 제공하고, 커널의 간섭 없이 애플리케이션 수준에서 이를 스케쥴링 및 컨텍스트 스위칭을 할 수 있도록 한다.

경량 스레드의 수동 구현

경량 스레드를 직접 구현하기 위해서는 크게 스케쥴러와 컨텍스트 스위칭 기능을 구현할 수 있어야 한다.

  • 스케쥴러: 현재 실행 중인 스레드를 다른 스레드로 교체하고, 일정한 규칙에 따라 스레드를 실행하는 역할을 한다.

  • 컨텍스트 스위칭: 경량 스레드 간의 문맥 전환을 하려면 CPU 레지스터, 스택 포인터 등을 저장하고 복원하는 과정이 필요하다. 이는 주로 어셈블리어 수준에서 구현되는데, CPU 상태를 저장하고 다른 스레드로 전환하는 과정이 필요하다.

실제 적용 시 주의점

  1. 비동기 I/O: 비동기 처리를 통해 전체 성능 저하를 막기
  2. 커널 스레드와 혼합: 하이브리드 접근 방식에 해당되는데, 커널 스레드를 통해 I/O 블로킹 문제를 해결하면서 경량 스레드의 성능 장점을 살릴 수 있다.
  3. 스케쥴러 최적화: 유저 레벨 스케쥴러의 효율성이 좋을 수록 성능에 직접적인 영향을 미치므로, 스레드의 우선순위, 컨텍스트 스위칭 빈도 등을 각 상황에 맞게 최적화할 수 있어야한다.

특징

  1. 유저 레벨에서의 관리
  • 커널 모드의 개입 없이 유저 모드에서 동작한다. 이를 통해 컨텍스트 스위칭 비용을 줄이고 성능을 개선한다.
  • 운영체제가 이를 인식하지 못하므로, 여러 경량 스레드가 하나의 커널 스레드에서 실행 가능하다.
  1. 빠른 스케쥴링
  • 시스템 콜과 같은 운영체제 자원의 추가 소모가 없기 때문에 더 적은 오버헤드를 가질 수 있다.
  1. 운영체제와 독립적인 동작
  • 커널 스레드는 운영체제에 의해 스케쥴링되지만, 경량 스레드는 유저 레벨에서 스케쥴링을 담당하므로 운영체제가 이를 알지 못함.
  • CPU 코어 수 등에 종속되지 않고 많은 경량 스레드를 운용할 수 있다.
  1. 블로킹 문제
  • 유저 레벨에서 관리되므로, 하나의 경량 스레드가 블로킹되면 같은 커널 스레드에서 동작하는 다른 경량 스레드가 영향을 받을 수 있다. 이를 위해 비동기 I/O 혹은 다중화 기법 등을 적용해야한다.