2017-05-03 89 views
3

我正在構建一個OpenGL應用程序。它與OpenGL唯一不方便的地方是它使用了少量(5個或更多)相當大(2000x2000及更大)的紋理。其餘的是非常默認的現代OpenGL 3.3的東西(FBO的,VBO的,IBO的,VOA的,着色器等)。由於這些紋理非常大,需要的位深度超過8位,因此我使用內部像素格式來減少內存(但是,將其更改爲簡單的內容並不會幫助(請參見下方))。現在,這裏是一個事物:完全相同的代碼,運行在Windows,Linux和MacOS上(我使用SDL作爲抽象層)。在同一硬件上(我的2011年末MacBook Pro 13「,Intel HD Graphics 3000 @ 1280x800),同樣的編譯器(clang -O3 -mavx),Linux和macOS之間的性能差異是巨大的在macOS上,我的幀時間大約是30ms到80ms。然而,在Linux上,這是一個驚人的1ms到4ms。同樣的筆記本電腦,只是在不同的操作系統中重新啓動。縮短應用程序窗口大約600x400,在macOS上將幀時間降低到13ms因此,像素着色器/光柵化(我的着色器的確是非常複雜的)Linux與macOS,相同硬件的巨大OpenGL性能差異

我必須說我在macOS上有更好的幀時間(大約13ms到20ms)所以,在發現這些之後我越來越懷疑Apple可能會通過系統更新有意地「降級」英特爾HD Graphics 3000的圖形驅動程序,以將購買者推向b你的新產品。我必須說,我一直在考慮購買一臺新的筆記本電腦,但是自從我發現這一點以後,突然感到厭惡。

現在的問題是:你認爲在這裏會發生什麼?越野車司機?蘋果故意讓事情變慢?驅動程序中包含一個未優化的GLSL編譯器?或者,也許在應用程序中的OpenGL代碼中有一些不好的做法?驅動程序對非8位紋理格式的支持很普遍嗎?

我只是討厭這個應用程序在Linux中非常棒,在macOS中非常令人愉快。硬件能夠做得更好。


一些測試,如通過要求@BDL:

  • 通過因子4在每一個降維的尺寸紋理(因而16次存儲器少,留給我們一個500×500的紋理,大約),不影響幀時間。
  • 使用GL_RGB8或GL_SRGB8作爲內部格式不會影響幀時間。
  • 減少很多着色器的複雜性確實有幫助:當我在片段着色器中刪除大量計算時,我可以將其平均降低到8ms。

我會嘗試一個GLSL着色器優化的明天:https://github.com/aras-p/glsl-optimizer 希望這有助於一點。

+0

@NicolBolas我希望你停下來:) –

+0

你應該使用儀器和/或OpenGL Profiler來描述你的應用程序。它使用了很多CPU時間嗎?它花了很多時間在紋理格式轉換?你也應該試一試你的代碼。你使用'GL_R11F_G11F_B10F'似乎是問題的可能原因。 –

+0

難道你不能再縮小性能有問題的部分嗎?例如,是否使用較小的紋理幫助?降低着色器複雜性有助於嗎?在MacOS上,哪些OpenGL調用佔用了所有時間? – BDL

回答

-2

這通常很難得到這些問題上堆棧溢出的底部,因爲我們沒有訪問您的代碼,但這裏有一些東西,你可以嘗試:

  • 更新驅動程序到最新版本受OS支持。
  • 打開圖形調試器並檢查緩衝區大小,紋理大小,RAM使用情況,內存使用情況等。

這可能只是一些時間問題,必須在OSX和Linux之間進行排序,您還可以通過SDL獲取指向原始窗口資源的指針並以此方式解決問題。

+2

「更新驅動程序」?你意識到圖形驅動程序是Mac OS操作系統的一部分,對吧? – duskwuff

+0

你能否詳細說明「解決時間問題」?你在談論什麼時機問題? –

+0

@MartijnCourteaux您是手動設置framelimit還是應用程序運行得儘可能快? –

2

你用什麼方法來測量幀渲染時間?在我關於各種OpenGL實現的時序行爲的實驗中,Mesa/Intel HD驅動程序有關於最難解釋時序行爲的內容。

用於MacOS X的Intel HD Graphics驅動程序是一個完全不同的代碼庫(零源代碼重疊!),由一個完全不同的開發團隊(主要是Apple People AFAIK)編寫。

請記住,OpenGL採用異步執行模型,說明緩衝區交換調用的確切時間沒有硬指定。在Linux上,AMD和NVidia OpenGL幾乎都有…SwapBuffers區塊,直到V-Sync(如果啓用V-Sync)。然而,我發現Mesa/Intel實現將…SwapBuffers視爲另一個排隊命令,只有命令隊列已滿並且正在進行的調用最終只能在緩衝區交換後才能執行(如清除後臺緩衝區)。

爲了削減長話短說,我發現實際測量幀渲染免耕presentation¹通過將glClear通話時間正確…SwapBuffers(即結算爲下一個幀的來下一次迭代中唯一可靠的方法)並測量從渲染開始到異常放置glClear之後的時間。

無論如何,通過查詢對象可以更好地測量純粹的渲染時間(不包含表示部分)。