2012-01-17 34 views
11

Ben parametreleri beri 1000000 x 100 iki boyutlu küresel iş büyüklüğü ve 1 x 100 Ancak bu derlemeye reddederOpenCL'de yerel bellek nasıl bildirilir?

__kernel void myKernel(
     const int length, 
     const int height, 
     and a bunch of other parameters) { 

    //declare some local arrays to be shared by all 100 work item in this group 
    __local float LP [length]; 
    __local float LT [height]; 
    __local int bitErrors = 0; 
    __local bool failed = false; 

    //here come my actual computations which utilize the space in LP and LT 
} 

yerel bir çalışma boyutu ile aşağıda OpenCL çekirdeği koşuyorum length ve height derleme zamanında bilinmemektedir. Ancak, bunun nasıl doğru bir şekilde yapılacağı açık değildir. Memalloc ile işaretçileri kullanmalı mıyım? Bu işlem, belleğin yalnızca çalışma grubu için bir kez değil, iş öğesi başına bir kez ayrılacağı şekilde nasıl kullanılır?

İhtiyacım olan tüm çalışma grubu (yani, 100 iş öğesinin tümü) arasında paylaşılan 2 düz şema, 1 int ve 1 boolean dizisi.

kernel void myKernel(const int length, const int height, local float* LP, 
        local float* LT, a bunch of other parameters) 

Daha sonra value ait olan kernelargument ayarlayın: Ama bu işi doğru yapan herhangi bir yöntem ...

+0

http://stackoverflow.com/questions/2541929/how-do-i-use-local-memory-in-opencl –

cevap

23

Nispeten basit, size çekirdeğe argümanlar olarak yerel diziler geçebilir oluyor bulmak için başarısız NULL ve bir size bağımsız değişken için ayırmak istediğiniz boyuta eşittir (bayt cinsinden). Bu nedenle olmalıdır:

clSetKernelArg(kernel, 2, length * sizeof(cl_float), NULL); 
clSetKernelArg(kernel, 2, height* sizeof(cl_float), NULL); 

yerel bellek her zaman (özel aksine) çalışma grubu tarafından paylaşılan, bu yüzden bool ve int ince olması gerektiğini düşünüyorum, ama eğer her zaman çok argüman olarak bu iletebilirsiniz edilir.

Sorununuzla gerçekten ilgili olmayan (ve bununla ilgili olarak hangi donanımı çalıştırmayı planladığınızı bilmediğimden, alakalı olması gerekmez), ancak en azından gpus, belirli bir gücün katları olmayan çalışma kağıtları gibi iki (Ben nvidia, 64 için amd için 32 olduğunu düşünüyorum), bu muhtemelen son 28 temelde boşa harcanan 128 maddeden oluşan çalışma grupları yaratacaktır. Eğer gpu üzerinde opencl çalıştırıyorsanız, doğrudan 128'lik çalışma gruplarını kullanırsanız (ve global çalışma boyutunu uygun şekilde değiştirin) performansa yardımcı olabilirsiniz

Yan not olarak: Neden herkesin alt çizgi varyantını neden kernel, local and global için kullandığını anlamadım, bana çok çirkin görünüyor.

+0

Hmmm ... bu yüzden nasıl bu çalışma grubu boyutu sorunu çözmek gerekir?100, nominal bir değerdir, sorunun tam örneğine bağlı olarak değişebilir, ancak global girişin her 1x100 alt bloğu için bu yerel bellek değişkenlerine ihtiyacım var. Bu alt bloğun bir çalışma grubu olmaması halinde, uygun 1x100 alt bloğu arasında bir değişken oluşturmanın bir yolu bulunmadığını varsayar mıyım? (Ve yan nota gelince, __ denemedim, ipucu için teşekkürler!) – user1111929

+0

Muhtemelen iki boyutlu bir diziyi daha sonra belleğe geçirmeliyim, ama bunu nasıl yapacağım? ClSetKernelArg (kernel, 2, length * local_work_size [0] * sizeof (cl_float), NULL) satırları boyunca bir şey iletebilirim; ancak bu tek boyutlu bir dizidir. Bunu 2 boyutlu hale getirmek daha iyi olur mu, değil mi? – user1111929

+0

Ayrıca, bool ve int iyi değildi, bir "error: variable" bitErrors "başlatılamadı" alıyorum. Yukarıdaki yerel ifadelerinizle değiştirirseniz, hata alıyorum: bir parametre, adlandırılmış bir adres alanına tahsis edilemez. Tabii ki 1 uzunluğunda bir dizi yapabilirim, ama bu gerçekten en güzel çözüm değil ... :-) – user1111929

1

Tüm yerel belleğinizi, özellikle bir dizi yerine basit bir değişken olduğunda, çekirdek dışında ayırmanız gerekmez.

Kodunuzun derlenememesinin nedeni, OpenCL'nin yerel bellek başlatmayı desteklememesidir. Bu belgede (https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/local.html) belirtilmiştir. Bu CUDA'ya


ps (Is there a way of setting default value for shared memory array?)

da mümkün değildir: Grizzly dan cevap yeterince iyi ve ben bir yorum olarak yayınlamayın eğer daha iyi olurdu, ama itibar politikası tarafından kısıtlanmış ediyorum. Afedersiniz.

__local float LP[LENGTH]; 

Ve sizin çekirdek derlemek tanımlamak olarak UZUNLUĞU geçmesi:

0

Ayrıca bu gibi diziler de tanımlanabilir olabilir.

clBuildProgram(program, 0, NULL, "-DLENGTH=128", NULL, NULL); 
İlgili konular