2014-10-02 40 views
5

我正在使用OpenCL(在輔助GPU上)生成一個多GPU設置(Mac Pro 2013年末)中的OS X應用程序紋理,後來用OpenGL(在主GPU上)繪製到屏幕上。該應用程序是CPU綁定因)調用glBindTexture(),並在glBegin(,兩者基本上花光了自己的時間:glBindTexture()中的OpenGL/OpenCL Interop性能glBegin()

_platform_memmove$VARIANT$Ivybridge 

這是視頻驅動程序的一部分:

AMDRadeonX4000GLDriver 

設置:創建紋理的OpenGL(glPixelBuffer),然後它的OpenCL的對應物(clPixelBuffer)。

cl_int clerror = 0; 
GLuint glPixelBuffer = 0; 
cl_mem clPixelBuffer = 0; 

glGenTextures(1, &glPixelBuffer); 
glBindTexture(GL_TEXTURE_2D, glPixelBuffer); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_FLOAT, NULL); 
glBindTexture(GL_TEXTURE_2D, 0); 

clPixelBuffer = clCreateFromGLTexture(_clShareGroupContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, glPixelBuffer, &clerror); 

圖形代碼:將OpenGL紋理映射到視口上。整個NSOpenGLView就是這一個紋理。

glClear(GL_COLOR_BUFFER_BIT); 

glBindTexture(GL_TEXTURE_2D, _glPixelBuffer); // <- spends cpu time here, 
glBegin(GL_QUADS);        // <- and here 
glTexCoord2f(0., 0.); glVertex3f(-1.f, 1.f, 0.f); 
glTexCoord2f(0., hr); glVertex3f(-1.f, -1.f, 0.f); 
glTexCoord2f(wr, hr); glVertex3f(1.f, -1.f, 0.f); 
glTexCoord2f(wr, 0.); glVertex3f(1.f, 1.f, 0.f); 
glEnd(); 
glBindTexture(GL_TEXTURE_2D, 0); 

glFlush(); 

獲得紋理存儲器的控制(通過clEnqueueAcquireGLObjects())後,OpenCL的內核將數據寫入紋理,然後釋放它的控制(通過clEnqueueReleaseGLObjects())。紋理數據不應該存在於主內存中(如果我正確理解了這些)。

我的問題是:預計CPU時間會花費在memmove()上嗎?它是否代表我的代碼中存在問題?或者是驅動程序中的錯誤,也許?我的(毫無根據的)懷疑是紋理數據正在通過:GPUx - > CPU/RAM - > GPUy,我想避免。

+0

你有交火/ sli連接嗎?什麼是您的pci-e版本和帶寬?你的質感有多大? – 2014-10-03 08:53:34

+0

這是Mac OS X,所以沒有Crossfire或SLI支持。每個GPU具有15.7GB /秒的PCIe 3.0帶寬(每個16通道)。我的應用程序正在使用(取決於配置)在2048x2048的1到3個紋理之間。 – senojsitruc 2014-10-03 12:19:28

回答

2

之前我接觸的內存傳輸,我的第一個看法是,你使用的是不會是你最好的朋友,因爲

1)這直接繪製不能很好地與司機工作clBegin() 。使用VBOs等代替,因此這些數據可以存在於GPU上。

2)在OS X上,這意味着您處於舊的兼容性上下文中,而不是新的核心上下文。 (據我所知)新的上下文是一個完整的重寫,這是未來的優化將最終結束,而你正在使用的上下文(可能)只是維護。

因此,在GL端的內存傳輸....你是在glCreateSyncFromCLeventARB()和glWaitSync()?應該沒有必要在代碼中看到glFlush()。一旦你擺脫了即時模式的繪製(如上所述)並且使用兩個API之間的同步對象,你的主機代碼應該什麼都不做(除非要求驅動程序告訴GPU做什麼)。這會給你最好的機會,讓你有最快的緩衝區副本....

是的,副本:(因爲你的CL紋理物理上生活在一個不同的GPU內存到GL紋理,必須複製PCIe總線的速度會很慢(這是你在分析過程中看到的情況)實際發生的事情是,CPU將GPU內存A和GPU內存B映射到固定的主機內存,然後在它們之間進行拷貝(希望)一個DMA,我懷疑數據實際上是觸及系統內存的,所以這個舉動是GPUx - > GPUy。

試着把你的CL和GL上下文放在同一個GPU上,我想你會看到你的傳輸時間消失。最後的想法是:如果你的CL計算被傳輸時間拖垮了,最好把上下文粘在同一個CPU上。你有經典的CPU/GPU任務分割問題。

+0

感謝您的回覆。我會盡快嘗試! – senojsitruc 2014-10-24 17:20:23