SW Rasterize 기법에 따른 효용성 요약

SW Occlusion Culling만들면서 CPU로 삼각형 찍는 방법으로 별 짓을 다 써봤다. SW Occlusion Culling을 수행하기 위해선 프레임버퍼에 삼각형의 depth를 출력해야한다. depth값이 아닌 color값이나 texture를 출력하는 경우도 기본 원리는 똑같다. 성분의 종류만 다르고 1/w로 보간하는것까지 똑같다. 즉 CPU로 삼각형 찍는 SW Rasterizer를 만드는 작업이다. 여러가지 기법들을 사용해봤는데 결론을 요약해본다.

1. Multi-Thread 사용

  1. 화면 구역을 나눠서 여러스레드가 동시에 rasterize하기 – (탈락)
  2. 스레드 개수만큼 라인을 건너뛰면서 (interlace 방식처럼) 여러 스레드가 동시에 rasterize – (탈락)
  3. 삼각형 변환 스레드와 raster스레드를 나눠서 파이프라인 방식으로 rasterize하기 – (탈락)
  4.  

시간을 길게 잡고 전체 처리량으로 보면 성능이 확실히 올라가지만 다음의 이유들로 응답성은 크게 떨어진다.

  • 스레드간 동기화 – (아무리 가벼운 락(atomic연산)을 사용해도 최소한 버스는 잠궈야(asm 접두어 lock) 한다.
  • 터보부스트 꺼짐 – 스레드당 클럭이 떨어지므로 응답성에 더욱 악영향을 준다.

결론 – 멀티스레드는 사용하지 않는다. 오프라인 렌더링이면 모를까, 리얼타임으로 쓰기엔 적합하지 않다.

2. 삼각형 drawing방식

  1. 전통적인 삼각형 변환후 스캔라인을 따라 그리기 – (채택)
  2. Barycentric Coordinated방식 -임의의 점이 삼각형 안에 있을때 무게중심에 의하여 보간된 depth(color, tex도 가능)를 구한다. –  (탈락)
    • SIMD와 멀티스레드 적용에 유리하다. 근데 SIMD를 써도 전통적인 1번 방식보다 느리다. AVX로 8픽셀씩 동시 처리해도 전통적인 1번 방식보다 느리다. 기본적으로 메모리 읽고 쓰기가 훨씬 많이 발생한다.

결론 – 그냥 전통적인 삼각형 변환후 스캔라인을 따라서 보간된 depth(color, tex)를 찍는 방식이 제일 빠르다.

3. SIMD사용 (SSE/AVX사용)

  1. cmpps등의 명령어로 비교-분기가 아닌 xor mask를 이용한 비교-치환으로 depth버퍼에 써넣는다. SSE는 동시에 4픽셀, AVX는 동시에 8픽셀을 동시 처리한다.
  2. FPU로 처리하는 경우 xor mask를 이용한 비교치환보다 그냥 cmp(if)로 처리하는게 더 빠를수 있다.
  3. AVX 8샘플 처리를 우선시 하되 메모리 align에 따라서, 또는 짜투리 픽셀 개수에 따라서 AVX -> SSE -> FPU순으로 선택해서 처리한다. memory align이 필요하다.
  4. SIMD를 사용하더라도 픽셀 개수가 일정 이하(32개등)면 그냥 FPU로 처리하는게 더 빠르다.

화면을 꽉 채우는 정도의 삼각형 하나를 찍는다면 당연히 AVX – SSE – FPU순으로 성능이 나온다. 하지만 그런 경우는 별로 없고 작은 삼각형을 왕창 찍을 일이 훨신 많다.

작은 사이즈의 삼각형을 찍을때는 AVX가 SSE보다 느릴 때가 꽤 있으며 심지어 FPU – SSE – AVX순으로 성능 순위가 뒤바뀌는 경우도 허다하다. 따라서 그려야할 픽셀이 일정 개수 이하면 SIMD가 더 느리므로 그냥 FPU로 찍는다.

어딘가에서 본 자료에 의하면 AVX사용시 클럭저하가 있다고 하는데 확실히 알아보진 않았다. 그런데 경험상 그 얘기가 맞는것 같다.

결론 – 사용은 하되 압도적인 성능향상은 기대하지 않는다.


답글 남기기

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

WordPress.com 로고

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

Google photo

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

Twitter 사진

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

Facebook 사진

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

%s에 연결하는 중