2010-09-09 17 views
7

C programlamada kullanımını kullanarak, c programlamada kullanmak için CUDA C kodunda montaj kodunu kullanmak istiyorum.Montaj talimatlarını CUDA koduna koymak mümkün mü?

Mümkün mü?

+0

SU üzerinde İlgili: http://superuser.com/questions/668019/how-do-device-driver-instructions-program-the-gpu Intel'in Xeon Phi için mümkün görünüyor. –

+1

Olası çoğaltılabilir [GPU birleştirici nasıl oluşturulur veya değiştirilir?] (Http://stackoverflow.com/questions/4660974/how-to-create-or-manipulate-gpu-assembler) –

cevap

4

Hayır, yapamazsınız, C/C++ 'dan asm yapıları gibi bir şey yoktur. Yapabilecekleriniz, oluşturulan PTX montajını düzeltmek ve daha sonra CUDA ile kullanmaktır. Örnek için this adresine bakın.

Ancak GPU'lar için, derleme optimizasyonları gerekli DEĞİLDİR, önce bellek birleştirmesi ve kullanım durumu gibi diğer optimizasyonları da yapmanız gerekir. Daha fazla bilgi için CUDA Best Practices guide'a bakın.

+2

İkincisi! Benim deneyimime göre, CUDA programları neredeyse her zaman belleğe bağlı, hesaplanmış değil. – mch

+0

her ikisinden de teşekkürler. Sadece bölme ve modulo operasyonlarının sayısını azaltmak istedim, ancak şimdi hafıza konusuna odaklanacağım. – superscalar

+0

Not: En yeni mimariye karşı derleme yapıyorsanız (flag -arch sm_20 kullanarak), en yeni API şimdi tamamen ?? bölünme ve karekök için IEEE kayan nokta özellikleriyle uyumludur. Bir grup bölümünüz varsa ve ayrıca -arch sm_20 kullanıyorsanız, bayrağı kullanarak bir performans artışı için "daha az" uyumlu sürüme geri dönmeyi düşünebilirsiniz: __- prec-div = false__ http://forums.nvidia.com/lofiversion/index.php?t170749.html –

17

CUDA 4.0'dan beri, inline PTX CUDA takım zinciri tarafından desteklenir. Araçta, bunu tanımlayan bir belge vardır: Using_Inline_PTX_Assembly_In_CUDA.pdf

Aşağıda, CUDA 4.0'da inline PTX kullanımını gösteren bir kod verilmiştir. Bu kodun, CUDA'nın yerleşik __clz() işlevi yerine kullanılmayacağını unutmayın, sadece yeni inline PTX yeteneğinin yönlerini araştırmak için yazdım.

__device__ __forceinline__ int my_clz (unsigned int x) 
{ 
    int res; 

    asm ("{\n" 
     "  .reg .pred iszero, gezero;\n" 
     "  .reg .u32 t1, t2;\n" 
     "  mov.b32   t1, %1;\n" 
     "  shr.u32   %0, t1, 16;\n" 
     "  setp.eq.b32  iszero, %0, 0;\n" 
     "  mov.b32   %0, 0;\n" 
     "@iszero shl.b32   t1, t1, 16;\n" 
     "@iszero or.b32   %0, %0, 16;\n" 
     "  and.b32   t2, t1, 0xff000000;\n" 
     "  setp.eq.b32  iszero, t2, 0;\n" 
     "@iszero shl.b32   t1, t1, 8;\n" 
     "@iszero or.b32   %0, %0, 8;\n" 
     "  and.b32   t2, t1, 0xf0000000;\n" 
     "  setp.eq.b32  iszero, t2, 0;\n" 
     "@iszero shl.b32   t1, t1, 4;\n" 
     "@iszero or.b32   %0, %0, 4;\n" 
     "  and.b32   t2, t1, 0xc0000000;\n" 
     "  setp.eq.b32  iszero, t2, 0;\n" 
     "@iszero shl.b32   t1, t1, 2;\n" 
     "@iszero or.b32   %0, %0, 2;\n" 
     "  setp.ge.s32  gezero, t1, 0;\n" 
     "  setp.eq.b32  iszero, t1, 0;\n" 
     "@gezero or.b32   %0, %0, 1;\n" 
     "@iszero add.u32   %0, %0, 1;\n\t" 
     "}" 
     : "=r"(res) 
     : "r"(x)); 
    return res; 
}