2012-04-13 22 views
10

500x500 görüntü arasında (ancak boyutları da değiştirebilirim) ve çok küçük bir 2B çekirdeği arasında hızlı bir 2B evrimleşmesi gerçekleştirmek için günlerce CUDA çekirdekleriyle denemeler yapıyorum laplacian 2d çekirdeği, yani 3x3 çekirdeği .. tüm cuda iplikleri ile büyük bir avantaj elde etmek için çok küçüktür).CUDA küçük çekirdekli 2d evrişim - nasıl yapılır

Bir CPU klasik uygulaması oluşturdum (iki tane düşünmek kadar kolay döngü için) ve daha sonra CUDA çekirdekleri oluşturmaya başladım. Birkaç hayal kırıklığı denemeden sonra

Bu kod ile sona erdi daha hızlı bir konvolüsyonunu gerçekleştirmek için: http://www.evl.uic.edu/sjames/cs525/final.html (Paylaşılan Bellek bölümüne bakınız), temelde 16x16 ipler Yükü o paylaşılan hafızada ihtiyaç duyduğu tüm büklüm verilerini engelleyebilir sağlar ve daha sonra konvolüsyonu gerçekleştirir.

Hiçbir şey, CPU hala çok daha hızlı. FFT yaklaşımını denemedim çünkü CUDA SDK, büyük çekirdek boyutlarıyla verimli olduğunu belirtiyor. Eğer yazdığım her şeyi okumak

olsun ya da olmasın, sorum şu:

Ben nispeten büyük görüntü ve CUDA ile çok küçük bir çekirdeğin (3x3) arasında bir hızlı 2B konvolüsyonunu gerçekleştirebilirsiniz nasıl ?

+4

"CPU hala çok daha hızlı" ile ne demek istiyorsun? Belleğin GPU'ya kopyalanması ve/veya çekirdeğin başlaması ve tamamlanması için gereken süre dahil olmak üzere tüm programı zamanlıyor musunuz? –

+0

Şu an için zamanlamaya ihtiyacım yok, CPU ile programın LOT daha hızlı tamamlandığını görebiliyorum :( – paulAl

cevap

7

Bu 3x3 çekirdeğin FFT tabanlı yaklaşım için uygun olmadığından haktasınız. Bununla başa çıkmanın en iyi yolu, çekirdeği sabit belleğe itmektir (ya da bir fermi + kart kullanıyorsanız, bu çok fazla önemli olmamalıdır).

Çekirdek boyutunu bildiğinizden, bunu yapmanın en hızlı yolu, giriş görüntüsü/sinyalinin parçalarını paylaşılan belleğe okumak ve açılmış bir çoğaltma işlemi gerçekleştirmek olacaktır.

Eğer ArrayFire ve OpenCV yüksek geliştirme süresi çok kaydedebilirsiniz Konvolusyon rutinleri optimize Bu işlemi gerçekleştirmek için kütüphaneleri kullanmak isteyen varsa -

.

OpenCV'ye fazla aşina değilim, ancak ArrayFire'da aşağıdaki gibi bir şey yapabilirsiniz.

array kernel = array(3, 3, h_kernel, afHost); // Transfer the kernel to gpu 
array image = array(w, h, h_image , afHost); // Transfer the image to gpu 
array result = convolve2(image, kernel);  // Performs 2D convolution 

DÜZENLEME

ArrayFire kullanarak toplu işlem işlemdir ilave faydası paralel kıvrım gerçekleştirmesini sağlar.

-

array kernel = array(3, 3, h_kernel, afHost);  // Transfer the kernel to gpu 
array images = array(w, h, 10, h_images, afHost); // Transfer the images to gpu 
array res = convolve2(images, kernel); // Perform all operations simultaneously 

: 10 görüntüleri olsaydı sen, aşağıdaki gibi somehting yapabileceği aynı çekirdek kullanarak evriştirilir istediğiniz convolvutions Örneğin here

üzerinde toplu işlemleri desteklemek konusunda okuyabilir

Tam Açıklama: AccelerEyes'te çalışıyorum ve ArrayFire üzerinde aktif olarak çalışıyorum.

+0

Linkler öldü.Yaralanmaya hakaret eklemek için, bunların Wayback Machine arşivi açık bir şekilde temizlendi: http://www.accelereyes.com/robots.txt – Hjulle

+0

@Hjulle Accelereyes'den arrayfire'a yeniden pazarladık. Bağlantılar benim için mevcut belgelerimize yönlendiriliyordu. Sorun yaşarsan özür dilerim. Kodu ve linkleri güncel dizinin son halini yansıtacak şekilde güncelledim. –

+0

Rahatsız ettiysem özür dilerim, teşekkürler. OpenCV bağlantısı hala bozuk. – Hjulle