![](/img/trans.png)
[英]Using OpenGL Compatibility Profile with Intel HD GPU + Mesa
[英]OpenGL program with Intel HD and NVidia GPU usage
我是OpenGL的新手,我希望有人向我解釋程序如何使用GPU。
我有一個三角形數組(包含3個點的類)。 這是繪制它們的代碼(我知道這些函數是被刪除的)。
glBegin(GL_LINES);
for(int i=0; i<trsize; ++i){
glVertex3d((GLdouble)trarr[i].p1().x(), (GLdouble)trarr[i].p1().y(), (GLdouble)trarr[i].p1().z());
glVertex3d((GLdouble)trarr[i].p2().x(), (GLdouble)trarr[i].p2().y(), (GLdouble)trarr[i].p2().z());
glVertex3d((GLdouble)trarr[i].p3().x(), (GLdouble)trarr[i].p3().y(), (GLdouble)trarr[i].p3().z());
}
glEnd();
我還使用用於旋轉,轉換等的已刪除功能。
當數組大小超過50k時,程序運行速度很慢。 我試圖只使用英特爾高清或僅使用NVidia gtx860M(默認的NVidia程序允許選擇GPU),但它們都非常慢。 也許英特爾高清的工作速度更快。
那么,為什么這兩個GPU之間沒有區別呢? 使用着色器會使程序更快地運行嗎?
可能的瓶頸是在頂點上循環,訪問數組並在每次渲染時拉出頂點數據50000次,然后將數據發送到GPU進行渲染。
使用VBO確實會更快並且壓縮提取數據並在初始化時將其發送到GPU一次的成本。
即使使用用戶內存緩沖區也會加快速度,因為您不會調用50k函數,但驅動程序只能對相關數據進行memcopy。
當數組大小超過50k時,程序運行速度很慢。
在中間模式下繪制時的主要瓶頸是,所有頂點都必須在每個幀中從程序存儲器傳輸到GPU內存。 GPU和CPU之間的總線在它可以傳輸的數據量上受到限制,因此最好的猜測是,50k三角形的數量遠遠超過總線可以傳輸的數量。 另一個問題是,驅動程序必須處理你在CPU上發送給他的所有命令,這也可能是一個很大的開銷。
那么,為什么這兩個GPU之間沒有區別呢?
(通常)英特爾高清卡和NVIDIA卡之間存在巨大的性能差異,但它們之間的總線可能是相同的。
使用着色器會使程序更快地運行嗎?
它不會直接受到着色器用戶的好處,但肯定是將這些頂點存儲在gpu內存上(參見VBO / VAO)。 第二個改進是,你可以只使用一次繪制調用渲染整個VBO,這減少了cpu必須處理的指令量。
使用具有顯着不同性能潛力的兩個GPU看到相同的性能肯定會表明您的代碼受CPU限制。 但我非常懷疑其他答案/評論中關於性能瓶頸的一些理論。
司機開銷很可能是罪魁禍首。 每個三角形有50,000個三角形和3個API調用,這是每幀150,000個API調用,如果您的目標是60幀/秒,則為每秒900萬次API調用。 好多啊! 對於每個電話,您將擁有:
一個重要的方面使它比它需要的更糟糕:你正在使用坐標的double
值。 與使用float
值相比,這需要傳遞的數據量翻倍。 由於OpenGL頂點管道以單精度(*)運行,因此驅動程序必須將所有值轉換為float
。
我懷疑即使使用不推薦的立即模式調用,如果你開始對所有坐標使用float
(你自己的存儲,並將它們傳遞給OpenGL),你也可以獲得顯着的性能提升。 您還可以使用glVertex*()
調用的版本,該調用采用帶有指向向量的指針的單個參數,而不是3個單獨的參數。 對於float
向量,這將是glVertex3fv()
。
轉向維多利亞州立大學當然是真正的解決方案。 只要頂點數據不隨時間變化,它就會減少數量級的API調用次數,並避免任何數據復制。
(*)OpenGL 4.1增加了對double
頂點屬性的支持,但它們需要使用特定的API函數,只有在單精度浮點數不夠精確時才有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.