2014-02-21 1 views
9

다음은 매우 간단한 테스트 프로그램입니다. vsync가 비활성화되면이 프로그램은 100FPS에서 실행되고 거의 0 %의 CPU를 사용합니다. vsync를 활성화하면 60FPS 및 25 % (4 코어 시스템에서 한 코어의 100 %) CPU 사용률을 얻게됩니다. 이것은 Nvidia GPU를 사용하고 있습니다. 온라인 검색은 Nvidia 제어판에서 "멀티 스레드 최적화"를 비활성화하는 제안으로 이어졌습니다. 이렇게하면 CPU 사용률이 10 %로 감소합니다. 또한, SwapBuffers 후에 sleep을 호출을 제거하면 다중 스레드 최적화가 비활성화 된 경우에도 25 %의 사용률을 다시 얻게됩니다. 누구든지 이것에 대해 밝힐 수 있습니까? 내가 뭔가 잘못하고 있는거야? Nvidia의 OpenGL 구현이 절망적으로 결함이 있습니까?vsync (OpenGL) 사용시 CPU 사용률 100 %

#include <GLFW/glfw3.h> 
#include <thread> 
#include <cstdlib> 
#include <cstdio> 

int main(int argc, char *argv[]) 
{ 
    if(!glfwInit()) 
     exit(EXIT_FAILURE); 

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Vsync Test", nullptr, nullptr); 

    if(!window) 
    { 
     glfwTerminate(); 
     exit(EXIT_FAILURE); 
    } 

    glfwMakeContextCurrent(window); 

#ifdef USE_VSYNC 
    glfwSwapInterval(1); 
#else 
    glfwSwapInterval(0); 
#endif 

    glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 

    double lastTime = glfwGetTime(); 
    double nbFrames = 0; 

    while(!glfwWindowShouldClose(window)) 
    { 
     double currentTime = glfwGetTime(); 
     nbFrames++; 
     if (currentTime - lastTime >= 1.0) 
     { 
      char cbuffer[50]; 
      snprintf(cbuffer, sizeof(cbuffer), "OpenGL Vsync Test [%.1f fps, %.3f ms]", nbFrames, 1000.0/nbFrames); 
      glfwSetWindowTitle(window, cbuffer); 
      nbFrames = 0; 
      lastTime++; 
     } 
     glClear(GL_COLOR_BUFFER_BIT); 
     glfwSwapBuffers(window); 
     glfwPollEvents(); 
      //limit to 100FPS for when vsync is disabled 
     std::chrono::milliseconds dura(10); 
     std::this_thread::sleep_for(dura); 
    } 

    glfwDestroyWindow(window); 
    glfwTerminate(); 
    exit(EXIT_SUCCESS); 
} 

답변

7

나는 ", 대답은"난 정말 알고하지 않는 한, 대답으로이 줄 주저하지만 다행스럽게도 필자는 그것을 향해 되거 수 있습니다.

나는 nVidia GPU도 가지고 있으며, 똑같은 것을 느꼈다. 내 생각 엔 드라이버가 기본적으로 스핀 대기된다는 점이다 :

while(NotTimeToSwapYet()){} 

(또는 그 멋진 드라이버 버전처럼 보이는 무엇이든).

nvoglv32.dll의 스레드에서 일부 스택 추적을 샘플링 process hacker를 사용하여 약 99 %의 시간을 목록의 상단에있어 문제는 일반적으로 다운 스트림

같은 것들에서 어느

KeAcquireSpinLockAtDpcLevel()

입니다

KiCheckForKernelApcDelivery()EngUnlockDirectDrawSurface()

나는 잘 conclu를 호출하는 Windows 드라이버 프로그래밍에 충분히 정통한 아니에요 그러나 나는 확실히 나에게 내가 틀렸다라고 나에게 이야기하지 않는다.

그리고 당신이 분명히 잘못한 것처럼 보이지 않습니다. 비 독점적 인 Windows 응용 프로그램에서의 스왑 타이밍이 정말 고통 스럽다는 나의 경험이었습니다. 많은 시행 착오가 있었고, 서로 다른 시스템간에 많은 변동성이있었습니다. 내가 아는 한, 항상 잘 작동 할 "옳은"방법은 없습니다 (제발, 누군가 제 잘못이라고 말해줘!).

과거에는 vsync를 사용하여 CPU 사용량을 낮게 유지할 수 있었지만 (더 반응이 덜한 경우에도) 더 이상 문제가되지는 않습니다. 최근에 DirectX에서 OpenGL로 전환했기 때문에 NVIDIA의 드라이버가 최근에 변경된 것인지 또는 vsync와 관련하여 DX와 OpenGL을 다르게 취급하는지 여부를 알 수 없었습니다.

+1

확실하지는 않지만 확실히 도움이됩니다. 나는이 게시물 (http://forum.openscenegraph.org/viewtopic.php?t=3653#18283) 누군가가 드라이버 개발자로부터 피드백을 얻은 곳을 찾았습니다. 그들의 응답에 따르면, 운전자가 산출합니다. 이것을 직접 테스트하기 위해 3D 렌더링 스위트를로드하고 OpenGL 프로그램을 실행하는 동안 내 CPU 코어 4 개를 모두 최대한 활용하도록했습니다. CPU 사용률은 25 %에서 0 %로 증가했습니다. 그것은 핵심을 극대화하는 동안 보이는 것처럼 보이지 않습니다. –

+0

@Chis_F 고마워, 잘 알고있다. 하지만 높은 CPU 사용량에 대한 나의 주요 관심사는 랩톱이 저전력 모드로 들어가는 것을 방해한다는 것입니다. "인공적인"사용법이 거기에 변화를 가져올 지 모르겠습니다. 어쩌면 모바일 드라이버가 다르게 설정 되었기 때문에 테스트 할 필요가 없습니다. –

+0

그건 확실히 걱정거리입니다. 수율은 전력 소모에 관한 한 아무런 차이가 없지만 모바일 GPU의 드라이버는 다르게 작동합니다. –