opengl : glFlush () 대 glFinish ()
호출 glFlush()
과 glFinish()
. 의 실제적인 차이점을 구분하는 데 문제가 있습니다.
워드 프로세서는 그 말 glFlush()
과 glFinish()
하나가 차이가 있다는 것을, 그들은 모두 실행됩니다 확신 할 수 있도록 OpenGL은 모든 버퍼 작업을 밀어 버린다 glFlush()
반환 즉시 곳으로 glFinish()
블록 모든 작업이 완료 될 때까지.
정의를 읽은 후, 이것을 사용 glFlush()
한다면 OpenGL이 실행할 수있는 것보다 더 많은 작업을 제출하는 문제에 부딪 힐 것이라고 생각했습니다. 그래서, 시도하기 위해, 나는 나의 프로그램 glFinish()
을 a glFlush()
와 lo로 바꾸었고 , 보라, 나의 프로그램이 (내가 말할 수있는 한) 똑같이 실행되었습니다. 프레임 속도, 리소스 사용량, 모든 것이 동일했습니다.
그래서 두 호출 사이에 많은 차이가 있는지 또는 내 코드로 인해 다르지 않게 실행되는지 궁금합니다. 또는 하나를 사용해야하는 곳과 다른 곳을 사용해야합니다. 또한 OpenGL은 glIsDone()
버퍼링 된 모든 명령 glFlush()
이 완료 되었는지 여부를 확인하는 것과 같은 호출이있을 것이라고 생각했습니다 (따라서 실행될 수있는 것보다 더 빨리 OpenGL에 작업을 보내지 않음). .
내 코드는 일반적인 게임 루프입니다.
while (running) {
process_stuff();
render_stuff();
}
이러한 명령은 OpenGL 초기부터 존재합니다. glFlush는 이전 OpenGL 명령 이 유한 한 시간 내에 완료 되도록합니다 ( OpenGL 2.1 사양 , 페이지 245). 프론트 버퍼에 직접 그리면 OpenGL 드라이버가 너무 많은 지연없이 그리기를 시작합니다. 각 개체 다음에 glFlush를 호출 할 때 화면에서 개체마다 나타나는 복잡한 장면을 생각할 수 있습니다. 그러나 이중 버퍼링을 사용할 때 glFlush는 버퍼를 교체 할 때까지 변경 사항이 표시되지 않기 때문에 사실상 전혀 효과가 없습니다.
glFinish 는 이전에 실행 된 명령 [...]의 모든 효과가 완전히 실현 될 때까지 반환되지 않습니다 . 즉, 모든 마지막 픽셀이 그려지고 OpenGL이 더 이상 할 일이 없을 때까지 프로그램 실행이 여기에서 대기합니다. 프런트 버퍼로 직접 렌더링하는 경우 glFinish는 운영 체제 호출을 사용하여 스크린 샷을 찍기 전에 수행해야하는 호출입니다. 강제로 완료 한 변경 사항을 볼 수 없기 때문에 이중 버퍼링에는 훨씬 덜 유용합니다.
따라서 이중 버퍼링을 사용하는 경우 glFlush도 glFinish도 필요하지 않을 것입니다. SwapBuffers는 암시 적으로 OpenGL 호출을 올바른 버퍼로 지정 하므로 glFlush를 먼저 호출 할 필요가 없습니다 . 그리고 OpenGL 드라이버를 강조해도 상관 없습니다. glFlush는 너무 많은 명령으로 인해 질식하지 않습니다. 이 호출이 즉시 반환된다는 보장은 없으므로 (의미하는 것이 무엇이든간에) 명령을 처리하는 데 필요한 시간이 걸릴 수 있습니다.
다른 답변에서 암시했듯이 사양에 따라 좋은 답변은 없습니다. 의 일반적인 의도는 glFlush()
호출 후 호스트 CPU가 OpenGL 관련 작업을 수행하지 않고 명령이 그래픽 하드웨어로 푸시된다는 것입니다. 의 일반적인 의도는 glFinish()
반환 된 후 남은 작업이 남아 있지 않으며 결과도 모든 적절한 비 OpenGL API (예 : 프레임 버퍼에서 읽음, 스크린 샷 등)를 사용할 수 있어야한다는 것입니다. 이것이 실제로 발생하는지 여부는 운전자에 따라 다릅니다. 이 사양은 합법적 인 것에 대해 많은 관용을 허용합니다.
나는 항상이 두 명령에 대해 혼란 스러웠지만이 이미지는 나에게 모든 것을 명확하게 보여 주었다. 분명히 일부 GPU 드라이버는 특정 수의 명령이 누적되지 않는 한 하드웨어에 명령을 보내지 않는다. 이 예에서 숫자는 5 입니다.
이미지는 실행 된 다양한 OpenGL 명령 (A, B, C, D, E ...)을 보여줍니다. 상단에서 볼 수 있듯이 큐가 아직 가득 차지 않았기 때문에 명령이 아직 실행되지 않습니다.
중간에서 우리 glFlush()
는 대기열에있는 명령에 어떤 영향을 미치는지 봅니다 . 큐에있는 모든 명령을 하드웨어로 보내도록 드라이버에 지시합니다 (대기열이 아직 가득 차지 않은 경우에도). 이것은 호출 스레드를 차단하지 않습니다. 추가 명령을 보내지 않을 수도 있음을 운전자에게 알리는 것일뿐입니다. 따라서 대기열이 채워질 때까지 기다리는 것은 시간 낭비입니다.
맨 아래에는 glFinish()
. glFlush()
모든 명령이 하드웨어에 의해 처리 될 때까지 호출 스레드가 대기하도록한다는 점을 제외 하면과 거의 동일 합니다.
"OpenGL을 사용한 고급 그래픽 프로그래밍"책에서 가져온 이미지.
성능 차이가 보이지 않는다면 뭔가 잘못하고 있다는 의미입니다. 다른 사람들이 언급했듯이 둘 다 호출 할 필요는 없지만 glFinish를 호출하면 GPU와 CPU가 달성 할 수있는 병렬 처리가 자동으로 손실됩니다. 더 자세히 살펴 보겠습니다.
실제로 드라이버에 제출하는 모든 작업은 일괄 처리되어 나중에 하드웨어로 전송됩니다 (예 : SwapBuffer 시간).
따라서 glFinish를 호출하는 경우 기본적으로 드라이버가 명령을 GPU로 푸시하고 (그때까지 일괄 처리되고 GPU에 작업을 요청하지 않음) 푸시 된 명령이 완전히 완료 될 때까지 CPU를 멈 춥니 다. 실행. 따라서 GPU가 작동하는 동안 CPU는 작동하지 않습니다 (적어도이 스레드에서는). 그리고 CPU가 작업을 수행 할 때마다 (대부분 일괄 처리 명령) GPU는 아무 작업도 수행하지 않습니다. 예, glFinish는 성능을 저하시킬 것입니다. (많은 명령이 이미 일괄 처리 된 경우 드라이버가 일부 명령에서 GPU 작업을 시작할 수 있으므로 이는 근사치입니다. 명령 버퍼가 많은 명령을 저장할 수있을만큼 커지는 경향이 있기 때문에 일반적이지 않습니다).
이제 왜 glFinish를 호출하겠습니까? 내가 사용했던 유일한 시간은 드라이버 버그가있을 때였습니다. 실제로 하드웨어로 보내는 명령 중 하나가 GPU와 충돌하는 경우, 어떤 명령이 원인인지 식별하는 가장 간단한 옵션은 각 Draw 후에 glFinish를 호출하는 것입니다. 이렇게하면 충돌을 정확히 유발하는 원인을 좁힐 수 있습니다.
참고로 Direct3D와 같은 API는 Finish 개념을 전혀 지원하지 않습니다.
glFlush는 실제로 클라이언트 서버 모델로 거슬러 올라갑니다. 파이프를 통해 모든 gl 명령을 gl 서버로 보냅니다. 그 파이프는 버퍼링 될 수 있습니다. 모든 파일 또는 네트워크 I / O가 버퍼링 할 수있는 것과 같습니다. glFlush는 "버퍼가 아직 가득 차지 않았더라도 지금 전송하십시오!"라고만 말합니다. 로컬 시스템에서는 로컬 OpenGL API가 자체적으로 버퍼링 할 가능성이 적고 명령을 직접 실행하기 때문에 거의 필요하지 않습니다. 또한 실제 렌더링을 유발하는 모든 명령은 암시 적 플러시를 수행합니다.
반면에 glFinish는 성능 측정을 위해 만들어졌습니다. GL 서버에 대한 일종의 PING입니다. 명령을 왕복하고 서버가 "I am idle"이라고 응답 할 때까지 기다립니다.
요즘 현대의 지역 운전자는 유휴 상태라는 것이 무엇을 의미하는지 매우 창의적인 아이디어를 가지고 있습니다. "모든 픽셀이 그려집니다"또는 "내 명령 대기열에 공간이 있습니다"입니까? 또한 많은 오래된 프로그램이 코드 전체에 glFlush 및 glFinish를 코드 전체에 뿌렸 기 때문에 부두 코딩을하는 많은 최신 드라이버는 "최적화"로 무시합니다. 정말로 그들을 비난 할 수는 없습니다.
요약하자면 : 고대 원격 SGI OpenGL 서버용으로 코딩하지 않는 한 glFinish와 glFlush를 실제 작업이 아닌 것으로 간주합니다.
봐 가지고 여기를 . 요약하면 다음과 같습니다.
glFinish ()는 glFlush ()와 동일한 효과를 가지며, glFinish ()는 제출 된 모든 명령이 실행될 때까지 차단됩니다.
다른 기사에서는 다른 차이점에 대해 설명합니다.
- Swap functions (used in double-buffered applications) automatically flush the commands, so no need to call
glFlush
glFinish
forces OpenGL to perform outstanding commands, which is a bad idea (e.g. with VSync)
To sum up, this means that you don't even need these functions when using double buffering, except if your swap-buffers implementation doesn't automatically flush the commands.
There doesn't seem to be a way of querying the status of the buffer. There is this Apple extension which could serve the same purpose, but it doesn't seem cross-platform (haven't tried it.) At it quick glance, it seems prior to flush
you'd push the fence command in; you can then query the status of that fence as it moves through the buffer.
I wonder if you could use flush
prior to buffering up commands, but prior to beginning to render the next frame you call finish
. This would allow you to begin processing the next frame as the GPU works, but if it's not done by the time you get back, finish
will block to make sure everything's in a fresh state.
I haven't tried this, but I will shortly.
I have tried it on an old application that has pretty even CPU & GPU use. (It originally used finish
.)
When I changed it to flush
at end and finish
at begin, there were no immediate problems. (Everything looked fine!) The responsiveness of the program increased, probably because the CPU wasn't stalled waiting on the GPU. Definitely a better method.
For comparison, I removed finished
from the start of the frame, leaving flush
, and it performed the same.
So I would say use flush
and finish
, because when the buffer is empty at the call to finish
, there is no performance hit. And I'm guessing if the buffer were full you should want to finish
anyway.
The question is: do you want your code to continue running while the OpenGL commands are being executed, or only to run after your OpenGL commands has been executed.
This can matter in cases, like over network delays, to have certain console output only after the images have been drawn or the such.
참고URL : https://stackoverflow.com/questions/2143240/opengl-glflush-vs-glfinish
'program story' 카테고리의 다른 글
std :: vector 요소는 연속적입니까? (0) | 2020.08.18 |
---|---|
배치 파일 : 콘솔 창을 열어 두는 방법 (0) | 2020.08.18 |
Linux bash에서 물결표의 의미 (홈 디렉토리 아님) (0) | 2020.08.18 |
CSS transform을 사용한 후 흐릿한 텍스트 : scale (); (0) | 2020.08.18 |
Haskell 테스트 워크 플로 (0) | 2020.08.18 |