OpenMPI와 multithreading...
on
시뮬레이션 가속화의 핵심은 병렬화의 계층(Level)과 단위(Granularity)를 최적화하는 것이다.
단위가 작다면 GPU를 활용해 단일 워크스테이션만으로도 압도적인 처리량을 낼 수 있지만, 단위가 커질수록 멀티스레딩이나 Open-MPI 기반의 분산 처리를 검토하게 된다. 클러스터 자원 관리 권한이 제한적이라면 Slurm이나 SGE 같은 스케줄러 도입은 필수적이다.
최근 내가 직면한 문제는 병렬화 단위가 너무 커서 단일 애플리케이션 형태를 유지하며 스케줄러(Slurm/SGE)로 대량 투입하거나 Open-MPI를 적용해야 하는 상황이다. 여기서 발생하는 치명적인 병목은 동기화 과정에서의 자원 유휴(Idle) 문제다. 전형적인 MPI Reduce 방식은 특정 노드가 지연되는 ‘Straggler’ 현상이 발생하면, 나머지 N−1개의 노드가 단 하나의 노드를 기다리며 100% 점유율을 유지한 채 방치된다. 이는 막대한 컴퓨팅 자원과 에너지의 낭비다.
멀티스레딩은 공유 메모리를 통해 완료된 스레드를 즉각 회수할 수 있어 이 문제에 유연하지만, 멀티 노드 환경으로 확장하기 어렵다는 한계가 있다. 현재 내 모델은 규모가 크고 Random Seed에 따른 실행 시간 편차가 심해, 일괄 동기화 방식의 MPI는 효율이 극히 떨어진다.
결국 해법은 기민한 동적 스케줄링이다. 태스크를 미세하게 쪼개 가용 자원이 생길 때마다 즉시 할당하고 취합해야 한다. 다만 파일 기반의 중간 결과 생성과 사후 취합 방식을 선호하지 않기에, 현재는 멀티스레딩과 멀티 머신 작업을 수동으로 조합해 운용하고 있다.
구체적으로는 8~10코어 단위로 작업을 묶어 할당하는 식인데, 이 역시 시스템 자원을 완전히 극대화하지는 못한다. 16코어 CPU를 풀 로드로 돌리는 것은 물리적 부담이 크고, 그렇다고 실험 규모를 줄일 수도 없으니 에너지 효율과 성능 사이에서 골치 아픈 딜레마에 빠져 있다.
한때 대안으로 제시된 Ray를 시도해 보았으나, 상시 상주하는 Python 프로세스 기반의 구조가 체질에 맞지 않아 결국 폐기했다. 현재로서는 수동 제어의 번거로움을 감수하며 최적의 효율을 찾기 위한 씨름을 이어가고 있다.