2016-06-19 38 views
8

GPU hesaplamayı yönetmek için Julia'nın CUDArt paketini kullanmaya başladım. Ben gpu gelen verileri (örneğin, to_host() kullanarak) çekmek için giderseniz ben gerekli tüm hesaplamalar üzerinde gerçekleştirilmeden önce bunu yapmak emin nasıl merak ediyorum.Julia CUDArt ile nasıl senkronize edilir?

Bazı deneyler aracılığıyla, belirli CudaArray güncelleştirilirken to_host(CudaArray)'un görünmeyeceği anlaşılıyor. Yani, belki sadece bunu kullanmak güvenliği sağlamak için yeterli mi? Ama biraz şansa benziyor.

Şu anda, documentation paketinde gösterildiği gibi, çekirdeklerimi çalıştırmak için launch() işlevini kullanıyorum.

CUDArt belgeleri, Julia'nın @sync makrosunu kullanarak güzel görünmesini sağlayan bir örnek verir. Ama @sync amaçları için "işim" ile işim bitti ve çekirdek bir kez bittiğinde, launch() ile başlatılır başlatılmaz hareket etmeye hazırım. launch()'un çalışmasını anladığım kadarıyla - bu özelliği değiştirmenin bir yolu yoktur (ör. "Başlattı" işlevinin çıktısını almayı beklemek için).

Böyle bir senkronizasyonu nasıl yapabilirim?

cevap

1

Daha kurallı yolu, her cihaz için bir akış yapmak olduğunu düşünüyorum Bu akıntının hesaplamalarını bitirmesini beklemesini söyle. README'deki Akış örneklerine bakın.

+0

İyi nokta. Ben 'device_synchronize' bir dizi ayarda hala yararlı olabileceğini düşünüyorum. 1. Akımları argüman olarak almayan CUBLAS, CUSPARSE vb. Gibi diğer işlevlerle birlikte kullanabilirsiniz. Ayrıca, sadece tek bir GPU ile çalışıyorsanız, akışlara bile ihtiyacınız olmayabilir ve bu nedenle 'device_synchronize', daha basit uygulamalara yol açabilir. –

10

Tamam, CUDArt paketinde bir ton belge yok, ancak kaynak koduna baktım ve bunun nasıl yapılacağını açık bir şekilde görebiliyorum. Özellikle, şu anda aktif olan cihazdaki tüm çalışmalar bitene kadar bloke edilecek bir device_synchronize() fonksiyonunun olduğu görülmektedir. Böylece, özellikle şu iş gibi görünüyor:

using CUDArt 
md = CuModule("/path/to/module.ptx",false) 
MyFunc = CuFunction(md,"MyFunc") 
GridDim = 2*2496 
BlockDim = 64 
launch(MyFunc, GridDim, BlockDim, (arg1, arg2, ...)); 
device_synchronize() 
res = to_host(arg2) 

Burada dikkat edilecek bir şey daha varsa rağmen daha uzmanlığa sahip kimseden duymak isteriz. Eğer hesaplamalar yapması gerektiğini belirten sonra sonra @async bloğunun içinde, aşağıdakileri yapmanız wait(stream) işlevini kullanın

streams = [(device(dev); Stream()) for dev in devlist]

ve:

+7

Sadece bir uyarı ifadesi: belgelenmemiş işlevler dahili kullanım için mevcut olabilir (bu nedenle dokümantasyon eksikliği). Açıkçası, bu her zaman geçerli değildir, ancak, eğer bu işlevleri kullanırsanız, bir sonraki sürüme geçerken sorun yaşamaya başlıyor olabilirsiniz. Paket ve kütüphane sahipleri, küçük sürümler arasında bile belgelenmemiş özellikleri büyük ölçüde değiştiren veya tamamen kaldırma konusunda daha fazla rahat hissetme eğilimindedir. Dikkatli ilerleyin ve regresyon testleri yazdığınızdan emin olun. – JDB