2014-10-02 15 views
5

Bir OS X uygulaması üzerinde bir çoklu-GPU kurulumunda (Mac Pro 2013) çalışıyorum. daha sonra OpenGL (birincil GPU'da) ile ekrana çizilen doku. uygulama, temelde tüm zamanlarını harcama ikisi de glBindTexture() ve glBegin (çağrı), CPU-sınırdır:OpenGL/OpenCL Interop Performansı glBindTexture(), glBegin()

AMDRadeonX4000GLDriver 
: Video sürücüsünün bir parçasıdır

_platform_memmove$VARIANT$Ivybridge 

Kurulumu: OpenGL doku (glPixelBuffer) ve daha sonra onun OpenCL muadili (clPixelBuffer) oluşturur.

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); 

Çizim kodu: OpenGL dokusunu görünüm alanına eşler. Tüm NSOpenGLView sadece bu tek doku.

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() ile) doku bellek kontrolünü ele geçirdikten sonra OpenCL çekirdek dokusu veri yazar ve ardından (clEnqueueReleaseGLObjects() ile) bunu kontrolünü bırakır. Doku verileri ana bellekte asla bulunmamalıdır (eğer tüm bunları doğru anlarsam).

Sorum şu: memmove() 'de çok fazla CPU zamanı harcanması bekleniyor mu? Kodumdaki bir problemin belirtisi var mı? Ya da sürücüdeki bir hata, belki? Benim (asılsız) şüphe şu ki, doku verileri şu şekilde hareket ediyor: GPUx -> CPU/RAM -> GPUy, kaçınmak istiyorum.

+0

Çapraz ateşleme/kayma bağlantınız var mı? Pci-e sürümünüz ve bant genişliğiniz nedir? Dokunun ne kadar büyük? –

+0

Bu Mac OS X, bu yüzden Crossfire veya SLI desteği yok. Her bir GPU, 15.7GB/sn PCIe 3.0 bant genişliğine sahiptir (her biri 16 şerit). Ve benim app 2048x2048 de bir ve üç doku arasındaki (konfigürasyona bağlı olarak) ile çalışıyor. – senojsitruc

cevap

2

Ben hafıza transferi değinmek önce, benim ilk gözlem Eğer

1) Bu doğrudan çizim sürücüsü ile iyi çalışmaz, çünkü en iyi arkadaşınız olacak değil clBegin() kullandığınızdan emin olduğunu . Bunun yerine VBO'ları vb. Kullanın, böylece bu veriler GPU'da yaşayabilir.

2) OS X'de, eski çekirdek bağlamından ziyade eski uyumluluk bağlamında olduğunuz anlamına gelir. Yeni bağlamın (yeniden anladığım) tam bir yeniden yazım şeklidir; bu, kullanmakta olduğunuz bağlamın (muhtemelen) korunurken, gelecekteki optimizasyonların biteceği yerdir.

Bu yüzden bellek aktarımı için ... GL tarafındaki glCreateSyncFromCLeventARB() ve glWaitSync() içine mi koyuyorsunuz? Kodunuzda gördüğüm glFlush() için gerek yoktur. Anında mod çiziminden (yukarıda belirtildiği gibi) kurtulduktan ve iki API arasında senkronizasyon nesneleri kullandıktan sonra ana bilgisayar kodunuz hiçbir şey yapmamalıdır (sürücünün bir şey yapmasını GPU'ya söylemesini istemek dışında). Bu, hızlı arabellek kopyasına sahip olmanız için en iyi şansı verecektir.

Evet, kopyalar :(CL dokunuz fiziksel olarak GL dokusuna farklı bir GPU bellek parçası üzerinde yaşadığından, üzerinde bir kopya olması gerekecek. Yavaş olacak PCIe veriyolu Profilleme işleminizde gördüğünüz budur.Gerçekte olan, CPU'nun GPU bellek A ve GPU belleği B'yi sabitlenmiş ana bellekte eşlemesi ve daha sonra aralarında (umarım) DMA.Görüntünün fiilen sistem belleğine dokunmasından kuşku duyuyorum, bu yüzden hareket GPUx -> GPUy.

CL ve GL ortamlarınızı aynı GPU'ya koymaya çalışın ve aktarım sürenizin kaybolduğunu göreceksiniz.

Son düşünce: CL işleminiz aktarım süresinin gölgesinde kalıyorsa, içeriği aynı CPU'ya yapıştırmanız en iyisidir. Klasik CPU/GPU görev bölünmüş sorun var.

+0

Cevabınız için teşekkür ederiz. En kısa sürede deneyeceğim! – senojsitruc