2012-06-16 17 views
5

OpenCL programımda, her çekirdeğin erişebilmesi için ihtiyaç duyduğu 60+ global bellek arabelleği dolduracağım. Her bir çekirdeğin bu arabelleklerin her birinin yerini bilmesini sağlamak için önerilen yol nedir?Birçok bellek nesnesinin OpenCL çekirdeklerini bilgilendirmenin doğru yolu?

Tamponlar uygulamanın ömrü boyunca stabildirler - yani, uygulama başlangıcında arabellekleri tahsis edeceğiz, birden fazla çekirdek arayalım, daha sonra uygulama sonunda arabellekleri serbest bırakacağız. Bununla birlikte, içerikleri, çekirdekler onlardan okuduğunda/yazdıkça değişebilir.

CUDA'da, bunu yaptığım gibi CUDA kodumda 60'tan fazla program kapsamı global değişkenleri oluşturmaktı. Daha sonra, ana bilgisayarda, bu küresel değişkenlere tahsis ettiğim aygıt arabelleklerinin adresini yazarım. Öyleyse, çekirdekler çalışmak için ihtiyaç duydukları arabelleği bulmak için bu küresel değişkenleri kullanırlardı.

OpenCL'de bunu yapmanın en iyi yolu ne olurdu? Görünüşe göre, CL'nin global değişkenleri CUDA'lardan biraz farklıdır, fakat CUDA metodumun çalışıp çalışmayacağı konusunda net bir cevap bulamıyorum, eğer öyleyse, tampon göstergelerinin global değişkenlere aktarılmasıyla ilgili nasıl gidileceği. Bu işe yaramazsa, aksi halde en iyi yolu nedir?

cevap

1

60 global değişkenler çok önemlidir! Algoritmanızı daha küçük veri parçaları kullanmak için biraz daha geliştirmenin bir yolu olmadığından emin misiniz? Unutmayın, her çekirdek asgari bir iş birimi olmalı, muazzam bir şey değil! Bununla birlikte, olası bir çözüm vardır. 60 dizinizin bilinen boyutta olduğu varsayılarak, hepsini tek bir büyük arabellekte saklayabilir ve daha sonra bu büyük dizinin çeşitli bölümlerine erişmek için ofsetleri kullanabilirsiniz. yalnızca çekirdeğe big_array ve uzaklıklar geçmesi gerekiyor, sonra

A is 100 elements 
B is 200 elements 
C is 100 elements 

big_array = A[0:100] B[0:200] C[0:100] 
offsets = [0, 100, 300] 

ve her dizi erişebilirsiniz: Burada üç dizilerle çok basit bir örnek. Örneğin:

A[50] = big_array[offsets[0] + 50] 
B[20] = big_array[offsets[1] + 20] 
C[0] = big_array[offsets[2] + 0] 

Bunun belirli cihazda önbelleğe etkileyecek, ama benim ilk tahminim ne kadar emin değilim "değil de." Bu tür bir dizi erişim de biraz kötü. Geçerli olup olmadığından emin değilim, ancak her bir çekirdeğinizi her ofseti ayıklayan ve orijinal işaretçinin bir kopyasına ekleyen bir kodla başlatabilirsiniz.

Dizininizde, dizilerinizi daha kolay erişilebilir tutmak için, clCreateSubBuffer: http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubBuffer.html'u kullanabilirsiniz; bu, ayrıca, diziler dizisi olmadan belirli dizilere başvuru göndermenize de olanak tanır.

Bu çözümün 60 çekirdek argümanını geçmekten daha iyi olacağını sanmıyorum, ancak OpenCL uygulamanızın clSetKernelArgs'ına bağlı olarak daha hızlı olabilir. Kesinlikle argüman listenizin uzunluğunu azaltacaktır.

+0

60 argümanı, bu kodun parçası olduğum bir araştırma projesi için özel bir kod sentezleyicisi tarafından üretilmesinden kaynaklanıyor. Maalesef bu kısmı kontrol edemiyorum. Belirttiğiniz tampon paketleme metodolojisini kullanarak bitirdim. Umarım 60 argümandan daha iyi bir yöntemdir. Yardım ettiğin için teşekkür ederim! – int3h

0

İki şey yapmalısınız.

kernel void awesome_parallel_stuff(global float* buf1, ..., global float* buf60) 

böylece çekirdek için her kullanılan tampon listelendiğini: Birincisi, her küresel bellek tampon kullanan her çekirdek için böyle her biri, bir şeyler bir argüman beyan etmelidir. Ve sonra, anasayfasında tarafında, her arabelleği oluşturmanız ve clEnqueueNDRangeKernel'u çağırmak için belirli bir kernel argümanına verilen bir bellek arabelleğini eklemek için clSetKernelArg kullanın.

Çekirdeklerin her çekirdek yürütme ile aynı arabelleği kullanmaya devam edeceğini düşünüyorsanız, yalnızca çekirdek argümanlarını bir zamanını ayarlamanız gerektiğini unutmayın. Gördüğüm yaygın bir hata, ana bilgisayar performansını düşürebilir, tamamen gereksiz olduğu durumlarda tekrar tekrar clSetKernelArg numaralı telefonu aramaktır.

+0

Bu nedenle, her çekirdek işlevi için 60 bağımsız değişkene sahip olmanın yolu yok mu? Tartışmaları etrafta tutabildiğimin farkındayım, ama bu, her parçacığın, sadece çekirdekler için hiçbir zaman değişmeyen ve aynı olan işaretçiler için 240 bayt bellek kullanarak başladığını gösterir. Ayrıca, argümanları geçerken potansiyel performans ek yükü vardır - bu çekirdekler 60 kez/saniye olarak adlandırılacaktır. – int3h