Skip to content

기술적 이슈

clomia edited this page Apr 28, 2021 · 13 revisions

다중 프로세스 채널링과 PropheticGrid [방대한 로딩시간을 완전히 제거]

프로세스 이름들

bprin : 2D 환경에서 UI와 게임을 제공 + 3D환경의 LoadField제공
(LoadField=로딩 대기가 필요할때 마인크래프트 클론 게임으로 이동되는데 이곳을 일컫는다)
simul : 3D 환경에서 진행되는 메인 게임 환경을 제공 (3D 세포 시뮬레이션이 시각화되는 field)
main : bprin,simul 프로세스를 중계,관리하며 LifeGame로직 연산이 메인 역할이다.

문제 요약

simul프로세스는 광활한 field를 로딩해야 하는데 우주는 4억Pixel이며, 실내를 구성하는 벽도 상당히 큰 이미지를 사용한다. 이로 인해 로딩 시간이 30초가량 소요된다. 또한, LifeGame로직 연산도 2차원이상의 무한한 시공간을 연산해야 하므로
가벼운 작업이 아니기 때문에 모든걸 단일 프로세스에서 실행하면 매우 긴 로딩시간을 감당해야 한다.
주요 로딩 요소: 그래픽 렌더링 + 매번 LifeGame로직을 연산하면서 생기는 버벅거림

무한한 시공간 연산을 "필요한 부분"만 연산하고, 새포 렌더링도 "변경된 부분"만 렌더링 하도록 하는
알고리즘이 작성된 클래스가 PropheticGrid 라는것을 짚고 다중 프로세스 채널링에 대한 설명을 먼저 합니다.

다중 프로세스 채널링

프로세스간 통신은 각 프로세스가 가진 별도의 통신 쓰레드에서 소켓을 통해 실행되며,
여러 쓰레드와 Queue를 사용해서 신호를 대기합니다. 이곳에서는 순차적+거시적으로 요약된 설명만 제공합니다.
상세한 구현은 client/core/core.ProcControll 클래스에서 팬아웃된 쓰레드와 프로세스들을 참조해 주세요.

제거된 지연시간들

  • simul프로세스가 LifeGame로직을 연산하는 시간이 제거됨. (인게임 버벅거림 해결)
  • simul프로세스가 로딩되는 시간이 은폐됨. (게임(시뮬레이션 단계)이 로딩되는 대기시간이 없어짐)

요약하자면 긴 로딩은 다른 프로세스가 따로 먼저 해주고, 부담되는 연산도 다른 프로세스에게 전부 제공받아서
사용자와의 I/O가 집중된 프로세스의 퍼포먼스를 끌어올리는 구조입니다.

순서. (대괄호나 중괄호로 묶인것은 물리적인 프로세스를 의미하며 그렇지 않은것은 프로세스가 제공하는 것(연산,서비스,게임 등)을 의미합니다)

    • {main}: [simul]프로세스와 [bprin]프로세스들을 모두 팬아웃 시킨 뒤, 두 프로세스와 통신 채널 구축(하위 프로세스와의 소켓통신에서 서버의 역할)
    • [simul]: {main}에 의해서 생성,실행.({main}프로세스와의 소켓통신에서 클라이언트의 역할)
    • [bprin]: {main}에 의해서 생성,실행.({main}프로세스와의 소켓통신에서 클라이언트의 역할)
      |
    • {main}: [bprin]프로새스로부터 초기정보를 얻은 뒤 [simul]프로세스로부터 완료 signal을 받았다면 [bprin]프로세스를 kill.
      또한, 초기정보를 사용해서 LifeGame로직을 연산하는 쓰레드 생성.
      (bprin창이 위 레이어에 있었기 때문에 사용자는 simul 창으로 이동하게 됨.)
    • [bprin]: 사용자에게 UI,bprin게임 환경을 제공, bprin게임을 통해서 초기정보를 얻은 뒤 {main}프로세스로 전송,
      ([simul]이 아직도 로딩중이라면 로딩 완료 될때까지 Load field(마인크래프트 클론)을 제공
    • [simul]: 그래픽 렌더링이 완료된 후 {main}프로세스에게 signal전송
      |
    • {main}: LifeGame연산을 하면서 연산결과를 [simul]프로세스에게 공급.
    • [simul]: {main}프로세스로부터 연산결과(delta)를 공급받아서 최소한의 부담으로 세포들을 렌더링.
    • [bprin]: 죽은 프로세스
      |
    • {main}: [simul]프로세스에게 게임 결과 수신후 (1)에서 진행한 [bprin],[simul]프로세스,쓰레드 팬아웃을 실행
    • [simul]: 게임이 종료되서 {main}프로세스에게 결과를 발신
    • [bprin]: {main}에 의해서 실행됨
      |
    • 모든 프로세스가 실행상태이다. 즉, 1의 상태로 돌아오게 되었으며, 위 단계를 반복할 수 있는 상태가 되었음.

이렇게 3개의 프로세스가 통신채널을 만들고 지속적으로 상호작용하는 패턴과 구조를 다중 프로세스 채널링이라고 부르고 있습니다.
매우 저수준에서 발생하는 문제 때문에 multiprocessing모듈을 사용할 수가 없어서
혹여나 착오가 생기는것을 방지하기 위해 멀티 프로세싱이라는 단어를 사용하지 않고 있습니다.

PropheticGrid

보류. 2차원 연산은 core/scripts/prophecy.py를 확인하세요.
코드에 한글로 설명된 주석이 충분히 작성되어있습니다.
또한 성능에 대한 내용은 밴치마킹 테스트 결과를 참고해주세요
원하신다면 PropheticGrid모듈을 사용해서 쉽게 테스트 해볼 수 있습니다.