Game Dev – Voxel Horizon에 CUDA적용 마무리.

오늘 메모리 사용량 최적화를 끝으로 CUDA적용은 마무리 지었다.
추가적으로 CUDA 사용이 필요할 경우 CUDA기능을 모아둔 dll라이브리에 기능을 추가하면 된다.

Voxel Horizon은 라이트맵(Light map)을 사용한다. 지형지물간의 그림자도 라이트맵을 구울때 ray와 삼각형들간 교차테스트를 수행해서 계산한다.
Voxel Horizon은 실시간으로 지형지물이 변화한다. 따라서 라이트맵을 다시 굽는 일이 수시로 발생한다. 네트워크로 복셀 오브젝트를 스트리밍했을때, 복셀들을 추가/삭제/편집 해서 복셀들간 지형지물이 변경될때 라이트맵(물론 전체가 아닌 일부 영역에 대해서)을 다시 구워야한다.

플레이중에 라이트맵 재계산으로 게임의 흐름이 끊기면 곤란하다. 프레임이 다소 떨어지더라도 불편함을 느끼지 않을 정도여야한다. 그래서 멀티스레드를 최대한 사용해서 악착같이 최적화했다.

그럼에도 불구하고 스트리밍한 오브젝트 개수가 너무 많을 경우나 맵을 한번에 로딩하는 경우에 라이트맵 계산으로 게임 루프가 비교적 오랜시간동안 멈출수 있다. 따라서 일정 시간을 초과하면 진행중인 라이트맵 베이킹을 끊고 다음번 프레임으로 넘긴다.
라이트맵 계산이 시작되면 완료될때까지 기본컬러-백색으로 렌더링 된다. 따라서 느린 머신에선 지형지물이 순백색으로 빛나는걸 꽤 오랫동안 지켜봐야할 수 있다.
4-6코어 데스크탑이라면 그다지 눈에 거슬리지 않는 정도로 빠르게 처리되지만 듀얼코어 머신(ex: Surface Book 1)에선 경우에 따라 꽤 거슬릴수도 있다.

내 테스트 머신중 기본사양으로 잡고 있는 것이 i5 Surface Book 1이다. 듀얼코어 모바일 i5 CPU , 8GB RAM, nvidia dGPU(GTX940m – 945m수준)를 장착했다.
코어는 두개뿐이고 클럭도 낮은 편이지만 nvidia GPU가 붙어있다. CUDA를 사용할 수 있다. 일단 하드웨어 구성상 CPU를 하나 더 장착한 셈이다. 물론 CUDA적용이 가능한 경우에만 그렇다. CPU와 GPU는 용도가 완전히 다르다.

사실 이번 CUDA적용 이슈는 Surface Book 1에서의 체감성능을 높이기 위함이 90%의 이유였다.
그리고 그 목적은 충분히 달성한 것으로 보인다.

최종적으로 CUDA적용 여부에 따른 성능 비교는 다음과 같다.
성능 비교를 위해 렌더링 루프를 중지하고 온전히 라이트맵을 계산하는 시간만을 측정했다.

[테스트 장비#1 : i7 8700K, GTX 970]
– CUDA : 12 threads ,12 cudaStreams -> 2335.41 ms
– CPU : 6 core 12 threads -> 8597.96 ms
CUDA로 계산하는 편이 약 3.7배 빠르다.
cuda_lightmap_bakcin_bench

[테스트 장비#2 : Surface Book 1, nvidia dGPU(GTX940m – 945m수준)]
– CUDA : 4 threads ,4 cudaStreams -> 6891.03 ms
– CPU : 2core , 4 threads -> 41028.14 ms
CUDA로 계산하는 편이 약 6배 빠르다.
cuda_lightmap_baking_bench_sb1

그리고 영상 비교.
늘 사용하는 테스트맵을 한방에 로드한 경우다. 5만여개의 오브젝트와 액면 수치상으로 1500만개 정도의 복셀이 배치된 맵이다.

맵 로딩은 다음과 같이 처리된다.
1. 복셀의 지오메트리 데이터 로드가 끝나면 멀티스레드로 삼각형 데이터를 만들어낸다.
2. 이 작업이 끝나면 라이트맵을 계산한다.
3. 게임루프가 정지하는걸 방지하기 위해 일정 시간이 지나면 라이트맵 베이킹을 취소하고 남은 오브젝트들의 계산은 다음 프레임으로 넘긴다.

2번이 시작되고 3번을 거쳐 라이트맵 계산이 완료될때까지의 과정을 영상으로 찍었다.
CPU만으로 처리하는 경우, CUDA를 사용하는 경우이다.
확연한 성능차이를 느낄 수 있다.

라이트맵 베이킹 외에 복셀 오브젝트가 x,y,z각 축에 대해 하나 이상의 완전한 구멍(터널)을 가지는지를 테스트하는 코드에도 CUDA를 적용했었다.
이 경우 한번에 모든 오브젝트를 테스트하는 경우는 압도적으로 CUDA가 빠르다.
물론 복셀 오브젝트들을 스트리밍했을때 오브젝트별로 이 테스트를 수행한다. 문제는 이때 기껏해야 100개 이하의 오브젝트들을 테스트하는 경우가 대부분이다. 이 정도의 적은 개수면 CUDA로 얻는 성능의 이득이 무의미해진다. GPU메모리에 데이터를 써넣고 계산 완료후 결과를 시스템 메모리로 가져오는 시간이 계산시간보다 훨씬 더 걸리기 때문이다.
따라서 실질적으로 별 쓸모는 없기에 기능만 만들어두고 사용은 하지 않는것으로 결론지었다.

Voxel Horizon에 CUDA적용 스토리는 이것으로 마무리. 끝.

 


답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중