본문 바로가기

개발/개발 일기

2021.7.19 개발 일기 - 레이트레이서에 멀티쓰레딩과 쓰레드 풀 적용

이전에 BVH 가속 구조를 레이트레이서에 적용하고 난 후에, 렌더링 타임을 약 35% 정도 단축시켰다. 하지만 아직 레이트레이서에 멀티쓰레딩을 적용하지 않았기 때문에 최근 며칠동안 레이트레이서에 멀티쓰레딩을 적용시키는 작업을 진행했다.

 

기본적으로 레이트레이서는 렌더링 전에 씬을 구성하고, 그 이후에는 씬이나 씬을 구성하는 기본체들의 변수가 바뀔 일이 없다. 그렇기 때문에 자원 경쟁에 대한 걱정없이 쉽게 멀티쓰레딩을 적용하는 것이 가능했다. 

 

멀티쓰레딩의 개념은 카메라의 위치에서 광선을 발사하고, 광선이 충돌한 위치의 픽셀 값을 정하는 로직에 적용되었다. 이 로직에서는 쓰기 작업을 하는 것들이 전부 로컬 변수였기 때문에, 작업을 잘 나눠주는 것만으로도 쉽게 멀티쓰레딩을 적용할 수 있었다. 

 

우선 적용하고 테스트한 결과를 보자. 테스트는 한 픽셀당 256개의 샘플링을 했고, 총 10번의 렌더링 타임의 평균값을 구했다. 

 

사진 1) 싱글스레드 레이트레이서
사진 2) 멀티쓰레드 레이트레이서
사진 3) 6쓰레드 테스트

대충 5배 정도의 성능 향상이 생겼다. 작업한 노트북의 CPU가 6코어 12쓰레드이었기 때문에, 약 10배 정도의 드라마틱한 성능 향상은 기대하지는 않았지만 그래도 8배 정도의 성능 향상은 기대했지만, 약간 실망이었다.

 

멀티쓰레딩의 쓰레드 수를 늘린다고 해서, 성능 향상이 리니어하게 일어나는 것은 아니지만 6쓰레드로 렌더링한 결과와 비교해서 50% 정도밖에 차이가 안나서 약간 실망했다(물론, 50% 향상도 많은 성능 향상이라고 생각한다).

 

이렇게 멀티쓰레딩을 구현하고, 사실 만족하려고 했지만 렌더링 퍼센트가 오르는 것을 보고 있자니 만족이 안되는 부분이 있었다.

 

테스트에 사용한 씬이 한가운데 투과성의 재질을 가진 구가 있다보니, 이 부분을 렌더링하는 쓰레드들이 다른 쓰레드에 비해서 렌더링이 너무 오래걸리다 보니깐 다른 쓰레드들이 자신의 역활을 다하고 노는 모습을 발견한 것이다. CPU면 CPU답게 멈추지 않고 일을 할 것이지 노는 것이 마음에 들지 않았기 때문에, 최대한 CPU를 혹사시키자라고 생각을 해서 쓰레드 풀을 적용해보았다.

 

쓰레드 풀을 적용한 결과는 아래와 같다.

 

사진 4) 쓰레드풀 레이트레이서

단순 멀티쓰레딩에 비해서 약 10% 정도의 성능 향상을 얻을 수 있었다. 이렇게 보면 큰 차이가 없는 것 같지만, CPU 사용 그래프를 보면 CPU가 조금 더 열심히 일하고 있다는 것을 알 수 있다. 

 

사진 5) 멀티쓰레드 적용 레이트레이서 CPU 사용량 그래프
사진 6) 쓰레드 풀 적용 레이트레이서 CPU 사용량 그래프

위 두 사진을 비교하면 차이를 바로 알 수 있다. 중간에 CPU 사용량이 갑자기 떨어지는 것은 1번의 렌더링이 끝나고 다음 렌더링으로 넘어갈 때이다.

 

멀티쓰레드를 적용한 레이트레이서의 CPU 사용량을 보면, 렌더링 초반 부를 제외하고 렌더링을 완료한 쓰레드가 늘어날 수록 사용량이 계속해서 줄어들는 것을 볼 수 있다.

 

그에 반해 쓰레드 풀을 적용한 대부분의 렌더링 타임에서 CPU를 계속해서 점유하고 있다가 다음 렌더링으로 넘어갈 때만 CPU 사용량이 떨어지는 것을 볼 수 있다. 

 

디버그 모드로 레이트레이서를 돌리게 되면 이런 차이가 더욱 두드러지게 나타난다. 

 

마지막으로 눈물나는 싱글쓰레드 레이트레이서 CPU 사용량 그래프이다.

사진 7) 싱글쓰레드 적용 레이트레이서 CPU 사용량 그래프

 

기본적인 패스트레이서를 구현한 이후로는 렌더링 타임이 너무 길어져서, 새로운 머티리얼을 적용하거나 새로운 샘플링 방법을 적용하더라도 테스트하는 것이 힘들었기 때문에 다른 작업보다 우선적으로 이 부분을 개선했는데, 꽤나 만족스러운 결과가 나온 것 같다.

 

또한 디버그 모드에서 쓰레드 풀로 렌더링을 하면 투과가 있는 현재 씬에서 약 20초 가량이 나오고 멀티쓰레드로 하면 약 23초 가량이 나오는데, 쓰레드 풀이든 멀티쓰레딩이든, 렌더링을 하는 동안 CPU를 다 점유해버리기 때문에 렌더링 타임동안 웹 서핑조차 못한다. 이럴 때 쓰레드 풀에서 쓰레드 하나만 줄여주면, 렌더링 타임은 멀티쓰레딩 정도 밖에 안걸리지만, 웹 서핑 정도는 문제없이 가능하다. ㅎㅎ

 

이제는 눈에 보이는 결과가 이뻐보이도록 레이트레이서에 여러 기능을 추가해볼까 한다.

 

이 글을 작성하고 나서 내 블로그 방문자 수를 보니깐 싱글쓰레드 사용량 그래프와 비슷한 수준이다... 언제쯤 쓰레드 풀을 적용한 것처럼 나올까?