TL;DR
- GameMath는 FreeBSD msun에서 파생된 독립형 C 수학 라이브러리로, IEEE 754 준수 시스템과 컴파일러·하드웨어 사이에서 일관된 부동소수점 연산을 제공함.
- 클라이언트가 각자 시뮬레이션 상태를 유지하는 게임의 락스텝 시뮬레이션(lock-step simulation)에서 바이너리 수준의 연산 불일치로 인한 동기화 이탈을 줄이는 용도임.
- 플랫폼별
libc수학 라이브러리 대신 공통 소프트웨어 구현을 사용해 CPU 모델과 라이브러리 버전에 따른 결과 차이의 한 가지 원인을 제거함. gmath.h와gamemath_static_lib를 통해 통합하며, 표준 C 수학 함수의 GameMath 버전은gm_접두사를 사용하고 현재는float정밀도 함수만 구현됨.- 일관성이 정확도보다 중요한 게임 네트워킹 관점의 라이브러리이며, 컴파일러의 FLT_EVAL_METHOD == 0 설정과
streflop등 대안의 특성을 함께 고려해야 함.
GameMath 개요
- GameMath는 FreeBSD msun 라이브러리에서 파생된 C 수학 라이브러리임.
- 자체 완결형 부동소수점 수학 라이브러리를 제공해 IEEE 754 준수 시스템에서 일관되게 동작하고, 컴파일러와 하드웨어 사이에서 부동소수점 연산을 재현 가능하게 만드는 것이 목적임.
- 네트워크 및 리플레이 코드가 클라이언트별 시뮬레이션 상태 유지에 의존하고, 클라이언트 사이에는 명령 목록만 전달하는 게임에 필요함.
- 이러한 락스텝 시뮬레이션에서는 바이너리 수준의 부동소수점 결과가 일치하지 않으면 시뮬레이션이 서로 달라져 동기화가 깨질 수 있음.
플랫폼 수학 라이브러리의 문제
- 플랫폼의
libc수학 라이브러리에 의존하는 방식은 여러 문제를 일으킬 수 있음. - 일부 라이브러리는 사용 가능한 경우 CPU의 초월 함수 명령을 호출하며, CPU 모델에 따라 서로 다른 결과가 나올 수 있음.
- CPU 명령을 사용하지 않는 경우에도 같은 플랫폼에서 라이브러리 버전이 업데이트되면 결과가 달라질 수 있고, 플랫폼 사이의 일관성도 거의 보장되지 않음.
- 공통 소프트웨어 라이브러리로 해당 연산을 처리하면 결과 불일치의 한 가지 원인을 제거할 수 있음.
사용 방법
- 권장 방식은 GameMath를 소스 트리에 포함하고
cmake에서 하위 디렉터리로 추가하는 것임. - 이후 주 바이너리를
gamemath_static_lib대상에 연결하고, 일반적으로math.h또는cmath를 포함하는 위치에gmath.h를 포함함. - 표준 C 수학 함수에 대응하는 GameMath 함수는
gm_접두사를 사용함. - 예를 들어
tanf대신gm_tanf를 사용함. - 현재는
float정밀도 버전의 함수만 구현됨.
부동소수점 일관성의 한계
- GameMath만으로 모든 부동소수점 결과의 일관성을 보장할 수 있는 것은 아니며, 특정 플랫폼의
libc구현과 동일한 정확도를 제공하지 않을 수 있음. - 게임 네트워킹 관점에서는 일반적으로 정확한 결과보다 일관된 결과가 더 중요함.
- SEI CERT C Coding Standard는 부동소수점 값을 다룰 때 고려해야 할 추가 문제와 완화 방법을 제시함.
- 가능한 경우 컴파일러가
FLT_EVAL_METHOD == 0이 되도록 구성하는 것이 권장됨. - x86 플랫폼에서는 일반적으로 SSE2 코드 생성을 활성화해 해당 설정을 적용함.
- GameMath의
float정밀도 구현 대부분은float정밀도만 사용하므로 SSE만 필요할 수 있음.
대안
- 부동소수점 수학 라이브러리를 찾을 때
openlim또는streflop을 접할 수 있음. - 두 라이브러리 중 순수 소프트웨어 구현을 사용하고 플랫폼과 컴파일러 사이의 일관된 결과를 목표로 하는 것은
streflop임. streflop은 GameMath보다 기능이 풍부하지만, 순수 C 인터페이스가 아닌 C++ 인터페이스만 구현함.- 또한
streflop은 LGPL 라이선스이므로 LGPL로 라이선스하지 않거나 LGPL의 제한을 따르지 않으려는 프로젝트에서는 특정 버전의 라이브러리를 정적으로 연결하는 데 제약이 있음.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요