2011-03-09 3 views
19

이 주제는 최적화 문제와 마찬가지로 많은 결과를 낳았지만, 내가 원하는 것 (생각)을 찾지 못했습니다.OpenGL 저수준 성능 질문

많은 자습서 및 SO 질문에도 유사한 도움말이 있습니다. 일반적으로 덮는 :

  • 사용 GL 얼굴 따라서 모델 번씩 버텍스 당에서 MVP 계산을 감소 (OpenGL의 기능이 아닌 현장 로직)
  • Only를 GPU (projectionModelView 조합) 1 행렬을 전송 컬링 (해야하는대로).
  • 사용 인터리브 정점
  • 많은 GL 일괄, 가능한 호출 최소화 적절한

그리고/아마도 몇 많은 다른 사람. 나는 (내 호기심 때문에) 여러 개의 버텍스 버퍼를 사용하여 2 천 8 백만 개의 삼각형을 렌더링했다. 나는 위의 모든 기술을 (최선을 다해서) 시도했으며, 성능 변화가 거의 없었다.

내 구현에서 약 40FPS를 받는다는 것은 아무 문제가 없지만 이러한 최적화 팁이 실제로 어디에서 사용되는지 궁금하다.

렌더링 중에 내 CPU가 약 20-50 % 공회전하므로 을 사용합니다. 나는 성능 향상을 위해 GPU를 사용하고 있습니다.

참고 : 속도를 채울 저장 그대로 내가

크로스 1은 분명하다 Game Development

답변

25

포인트에 게시 된 순간에 gDEBugger를로 찾고 있어요. 객체 뒷면의 프리미티브가 먼저 처리되면 이러한면은 생략됩니다. 그러나 현대 GPU는 오버 드로를 아주 잘 견딘다. 상당한 성능 저하가 발생하기 전에 한 번 (GeForce8800 GTX) 최대 20 %의 오버 드로를 측정했습니다. 그러나 오 클루 전 컬링 (occlusion culling), 블렌드 기하학 (blended geometry) 렌더링 등과 같은 것들을 위해이 예비를 저장하는 것이 좋습니다.

포인트 2는 무의미합니다. SGI Onyx를 계산하지 않으면 행렬은 GPU에서 계산되지 않습니다. 매트릭스는 항상 CPU에서 계산 된 일종의 렌더링 글로벌 매개 변수 였고, 현재는 유니폼이라고하는 GPU의 글로벌 레지스터에 푸시되므로 합류하면 거의 효과가 없습니다. 쉐이더에서 하나의 추가 벡터 행렬 곱셈 (4 개의 MAD 명령으로 축소) 만 저장하므로 알고리즘 유연성이 떨어집니다.

포인트 3은 모두 캐시 효율성에 관한 것입니다. 함께 속한 데이터는 캐시 라인에 맞아야합니다.

포인트 4는 상태 변경으로 인해 캐시가 삭제되는 것을 방지합니다. 그러나 그것은 GL이 어떤 것을 의미하는지에 달려 있습니다. 유니폼 교체는 저렴합니다. 텍스처 전환은 비용이 많이 듭니다. 그 이유는 유니폼이 캐시 된 일부 메모리가 아니라 레지스터에 앉아 있기 때문입니다. 셰이더를 전환하는 것은 비용이 많이 든다. 왜냐하면 서로 다른 셰이더가 서로 다른 런타임 동작을 보이기 때문에 파이프 라인 실행을 중단하고 메모리 (따라서) 캐시 액세스 패턴 등을 변경하기 때문이다.

그러나 이것들은 모두 마이크로 최적화입니다 (그 중 일부는 큰 영향을 미칩니다). 그러나 초기 Z 패스 구현과 같은 대규모 영향 최적화를 살펴 보는 것이 좋습니다. 초기 Z에서 오 클루 전 쿼리를 사용하여 전체 지오메트리 배치를 신속하게 구별합니다.근본적인 영향 최적화는 근본적으로 Point-4 마이크로 최적화와 같이 요약됩니다. 비싼 GL 상태로 렌더링 배치를 정렬하는 것입니다. 따라서 공통 셰이더를 사용하여 모든 것을 그룹으로 묶습니다. 그 그룹 내에서 텍스처별로 정렬합니다. 이 상태 그룹은 가시적 인 렌더 패스에만 영향을줍니다. 초기 Z에서는 Z 버퍼의 결과 만 테스트하므로 지오메트리 변형 만 있고 조각 쉐이더는 Z 값을 전달합니다.

+0

매우 좋습니다! 감사. –

+1

아주 좋은 대답입니다. 질문, 포인트 2에 대한 답변에서, 나는 약간 혼란스러워합니다. Shader 내부의 "모델 * 투영 * 뷰"(모델이 변경 될 때마다 유니폼 변수, modelview가 전송 됨)와의 차이점을 비교했습니다. 모델 당 업데이트 된 단일 균일 행렬 변수 (modelviewprojection) 대 정점 대신 CPU에 의해 계산됩니다 (한 번). 확실하게 그것은 많은 계산을 저장할 것입니까? – dcousens

+3

@Daniel : 일반적으로 셰이더에서 MVP 행렬을 계산하지 않습니다. 먼저 model_view_position = MV * vertex_position 계산을 수행 한 다음 clip_position = P * modelview_position을 수행합니다. 그 이유는 일부 알고리즘의 경우 전체 프로젝션 프로세스의 최종 결과뿐만 아니라 모델 뷰 변형 된 정점 위치가 필요하다는 것입니다. 또한 정점 법선은 전체 MVP^T^-1이 아닌 MV의 역 전치에 의해서만 변형됩니다. 그래서 또 다른 이유가 있습니다. 멋진 조명을 구현하려면 이러한 변형 된 법선이 필요합니다. – datenwolf

1

이것은 실행중인 하드웨어와 사용 시나리오가 무엇인지에 따라 다릅니다. 일반적인 경우에 OpenGL 성능 팁은 의미가 있습니다. 라이브러리는 결국 다양한 드라이버 구현에 대한 추상화입니다. 드라이버 제조업체는 자유롭게 최적화 할 수 있지만 원하는 경우 중복 상태 변경을 제거하거나 다른 최적화를 수행 할 수 있습니다. 다른 기기에서는 그렇지 않을 수 있습니다. 다양한 장치에서 우수한 성능을 발휘할 수있는 최상의 방법을 고수하는 것이 가장 좋습니다. 예

  • +0

    글쎄,이게 가장 좋을 것 같아, OpenGL과 관련된 최적화가 적고, 그래픽 프로그래밍의 좋은 습관 (성과 보람)에 더 가깝다. – dcousens

    +0

    현재 하드웨어 가속 그래픽 라이브러리를 최적으로 사용하기위한 몇 가지 일반적인 규칙은 다음과 같습니다. 너무 자주 상태를 변경하지 말고 배치 일괄 처리 배치를 변경하십시오. 그러나 최적화 규칙은 다른 세대의 하드웨어에 돌로 설정되어 있지 않으며, 오늘날의 모든 하드웨어는 사실이 아니며 향후 하드웨어에도 적용되지 않을 수 있습니다. 항상 캐시의 가치와 작업하고있는 하드웨어의 한계와 강점을 알고 있어야합니다. – Luther

    +0

    내가 들었던 지혜는 특정 하드웨어를 최적화하는 것이 바보 게임이라는 것입니다. 그 이유는 하드웨어 세대 간 또는 드라이버 버전간에 근본적으로 바뀔 수 있기 때문입니다. API 최적화 (이 경우 최소 상태 변경)와 더 이상 최적화 할 수없는 곳에서 하드웨어를 따라 잡는 것이 좋습니다. – Jherico

    3
    1. 은 (그들이 유니폼입니다 알고, 그래서 그리기 통화 중에 변경되지 않습니다) 당신을 위해 이러한 행렬을 결합 할 수있는 드라이버로 이해되지 않는다. 정확히 병목 현상입니다
    2. 는 CPU

    바인딩 경우에만 당신이 알아야 할 가장 먼저하는 일이다. GPU는 복잡한 시스템이기 때문에 대답이 아닙니다. 실제 문제는 이들 중 수 있습니다 :

    • 쉐이더 처리 (정점/단편/기하)
    • 채우기 속도
    • 그리기 수
    • GPU < 호출 -> VMEM (즉 어디 인터리빙 작은 텍스처 도움을)
    • 시스템 버스 (모든 프레임 일부 데이터를 스트리밍?) 당신은 프로를보고 테스트하는 일련의를 수행 할 필요가

    흠. 예를 들어 모든 것을 더 큰 FBO에 그려서 유효 노출 률 문제 (또는 MSAA 금액 증가)인지 확인하십시오. 또는 드로잉 호출 과부하 문제를 확인하기 위해 모든 것을 두 번 그립니다.

    +0

    왜 응용 프로그램이 CPU에 바인딩 된 경우에만 일괄 처리가 수행되어야한다고 말하는지 더 설명 할 수 있습니까? – ashishsony

    +0

    (원래 답은 2.5 년 전에 주어 졌으므로 내가 생각한 것을 기억하려고합니다 ...). GPU 쪽에서는 한 통화와 두 통화 사이에 약간의 차이가 있습니다. 그것은 CPU에서 수행되는 히트를 차지하는 드라이버 측의 호출 준비입니다. – kvark

    3

    @kvark 및 @datenwolf 답변에 2 센트를 추가하기 만하면되는데, 언급 한 포인트는 '기본'GPU 성능 팁이지만, 더 복잡한 최적화는 응용 프로그램에 따라 크게 달라집니다.

    지오그래픽 테스트 케이스에서는 초당 2800 만개의 삼각형 * 40 FPS = 11 억 2 천만 개의 삼각형을 던지고 있습니다. 이것은 이미 상당 부분입니다. 대부분의 (모든 Fari가 아닌) GPU에는 삼각형 셋업 GPU 클럭 사이클 당 1 삼각형의 성능. 800MHz로 동작하는 GPU가 초당 8 억개 이상의 삼각형을 처리 할 수 ​​없다는 것을 의미합니다. 이것은 단일 픽셀을 그리지 않고도 가능합니다. NVidia Fermi는 클록 사이클 당 4 개의 삼각형을 처리 할 수 ​​있습니다.

    하드웨어 플랫폼에 대해 언급하지 않고이 한도를 사용한다면 OpenGL/GPU 레벨에서 할 수있는 일은별로 없습니다. 당신이 할 수있는 것은 더 효율적인 도형 (절두체 또는 폐색)을 통해, 또는 LOD 체계를 통해보다 적은 형상을 전송하는 것입니다.

    또 다른 점은 픽셀의 정사각형 블록에서 래스터 화가 병렬 처리를 수행하므로 작은 삼각형이 채워지는 것을 방지 할 수 있다는 것입니다. http://www.geeks3d.com/20101201/amd-graphics-blog-tessellation-for-all/을 참조하십시오.

    +0

    흥미로운 링크이지만 '삼각형과 픽셀이있는 숫 사슴에 대한 강타'문으로 크기를 조정할 수있었습니다. 또한 주로 LOD 및 기타 약간 다른 최적화와 관련이 있습니다. 그래도 좋은 대답; 하드웨어 관련 팁을 찾지 않아서 하드웨어 사양을 표시하지 않았습니다. – dcousens