2014-02-21 65 views
9

這是一個非常簡單的測試程序。當禁用vsync時,該程序以100FPS運行,幾乎佔用CPU的0%。當我啓用vsync時,我得到60FPS和25%(4核系統上的一個核心的100%)CPU利用率。這是使用Nvidia GPU。在線搜索引導我建議在Nvidia控制面板中禁用「多線程優化」。這確實會降低CPU使用率,但只能降低到10%。此外,如果我在SwapBuffers之後刪除呼叫,即使禁用多線程優化,我也會再次獲得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()){} 

(或任何的那個花哨的驅動程序版本的樣子)。

使用process hacker品嚐來自nvoglv32.dll的線程一些堆棧跟蹤,這是在列表中約99%的時間頂部的事情是

KeAcquireSpinLockAtDpcLevel()

這通常是像

東西下游

KiCheckForKernelApcDelivery()EngUnlockDirectDrawSurface()

我不精通足夠的Windows驅動程序來調用這個conclu sive,但它肯定不會告訴我我錯了。

而且它看起來並不像你做任何明顯錯誤的事情。根據我的經驗,在非獨佔Windows應用程序中交換時機非常痛苦:涉及大量的試驗和錯誤,以及不同系統之間的很多變化。據我所知,沒有「正確」的方式來做到這一點,這一切都會很好地發揮作用(請告訴我,我錯了!)。

過去,我一直能夠依靠vsync來保持CPU使用率較低(即使它確實讓事情反應不靈敏),但似乎不再是這種情況。我最近從DirectX切換到OpenGL,所以我不能告訴你這是nVidia驅動程序的最近更改,還是他們只是將DX和OpenGL與vsync相區別。

+1

不是很確定,但肯定有幫助。我找到了這個帖子(http://forum.openscenegraph.org/viewtopic.php?t=3653#18283),其中有人從驅動程序開發人員那裏得到了一些反饋。根據他們的迴應,司機屈服。爲了測試我自己,我加載了我選擇的3D渲染套件,並在我運行OpenGL程序的同時,最大化了所有四個CPU內核。其CPU利用率從25%降至0%。它似乎雖然最大化了一個核心,但它實際上並不*它。 –

+0

@Chis_F謝謝,這是很好的知道(也有些鼓舞)。但我主要關心CPU佔用率高的問題,它不利於筆記本電腦進入低功耗模式;我不確定用法是否「人爲」會在那裏產生差異。也許移動驅動程序設置不同 - 我沒有一個測試。 –

+0

這當然是一個問題。就功耗而言,屈服不會產生任何影響,但也許他們的移動GPU的驅動程序運行方式不同。 –