HashLife 알고리즘을 활용하여 컨웨이의 생명 게임을 거의 무한대로 시뮬레이션하는 GOLDE 프로젝트 소개
C++23의 기능을 통해 코드 안전성, 가독성, 성능을 향상시켰으며, 특히 `std::jthread`와 `std::stop_token`을 활용하여 스레드 안전성을 확보
LifeNodeArena를 활용한 메모리 관리, `ankerl::unordered_dense`를 사용한 해시 테이블 구현 등, 현대 C++의 특징을 적극 활용
토로이드(Torus) 토폴로지 지원을 위한 추상화 설계, 임의의 스텝 사이즈(Step Size)를 지원하기 위한 Rokicki의 아이디어 차용
GOLDE는 HashLife 알고리즘을 사용하여 컨웨이의 생명 게임을 효율적으로 시뮬레이션한다. 핵심은 게임의 유니버스를 메모이제이션된 쿼드트리(Quadtree)로 표현하는 것이다. 각 노드는 미래 세대의 상태를 캐싱하며, 동일한 하위 패턴은 중복 계산되지 않도록 설계되었다. 특히, $2^n \times 2^n$ 크기의 노드는 $2^{n-2}$ 세대까지 계산할 수 있다. 이러한 접근 방식은 무한대 시뮬레이션(Infinite Simulation)을 가능하게 하는 핵심 원리이다.
저자는 C++23의 기능을 활용하여 코드의 안전성과 성능을 향상시켰다. 특히, `LifeNodeArena`를 사용하여 bump-pointer allocator를 구현, 메모리 할당의 효율성을 높였다. 또한, `std::construct_at`을 사용하여 placement new를 대체하고, `std::unique_ptr`와 커스텀 딜리터를 결합하여 메모리 관리를 단순화했다. 이러한 기법들은 를 방지하고, 코드의 가독성을 높이는 데 기여한다.
GOLDE는 사용자가 임의의 세대 수를 입력할 수 있도록 지원한다. 이를 위해 Golly의 접근 방식을 차용하여, 최대 $2$의 거듭제곱으로 스텝 사이즈를 분할하는 방법을 사용한다. Golly의 접근 방식은 캐시 효율성을 유지하는 반면, GOLDE는 각 단계에서 최대 $\log_2{n}$번의 점프를 통해 임의의 세대에 도달할 수 있도록 설계되었다. 이러한 접근 방식은 캐시 효율성(Cache Efficiency)과 유연성 사이의 트레이드오프를 보여준다.
GOLDE는 토로이드(Torus), 즉 도넛 모양의 유한한 그리드를 지원한다. 이를 위해 `Topology` 인터페이스를 활용하여 추상화(Abstraction)를 구현했다. `PrepareBorderCells`와 `CleanupBorderCells` 메서드를 통해 경계 조건을 처리하고, `LifeDataStructure`를 통해 데이터 구조를 추상화하여 다양한 토폴로지를 쉽게 지원할 수 있도록 설계했다. 이러한 설계는 알고리즘의 확장성(Algorithm Extensibility)을 높이는 데 기여한다.
댓글에서는 GOLDE가 지원하는 토폴로지(Topology)에 대한 논의가 이루어졌다. 특히, 구면(Sphere)과 같은 다른 토폴로지 지원 가능성에 대한 질문이 제기되었다. 또한, Rust로의 재구현을 제안하는 댓글도 있었다. 이는 C++의 복잡성에 대한 우려와 Rust의 안전성에 대한 기대를 반영하는 것으로 보인다. 전반적으로, 프로젝트의 기술적 깊이와 커뮤니티의 관심(Community Interest)을 확인할 수 있다.