2017-03-03 33 views
0

我在F#中做了一個小巧的函數式語言,它將編譯爲C++(大約第四次),並且想知道Nvidia的編譯器現在是否具有此功能。我希望他們這樣做,因爲它可以節省我不得不實施元組的努力,而谷歌搜索什麼也沒有。NVCC和NVRTC是否支持尾部呼叫優化?

但是,在Cuda用戶指南中搜索tail call也沒有,所以我猜這不太可能。

回答

0

簡短回答:是!

龍答:這個代碼

__device__ int i; 

__device__ int f2(int val) 
{ 
     if((val % 6) == 0) 
       return val; 

     return f2(val + 1); 
} 

__global__ void f1(int x) 
{ 
      i = f2(x); 
} 

int main() 
{ 
      return 0; 
} 

編譯時:

NVCC -keep -02 bla.cu

生成:bla.ptx

// 
// Generated by NVIDIA NVVM Compiler 
// 
// Compiler Build ID: CL-21124049 
// Cuda compilation tools, release 8.0, V8.0.44 
// Based on LLVM 3.4svn 
// 

.version 5.0 
.target sm_20 
.address_size 64 

     // .globl  _Z2f1i 
.global .align 4 .u32 i; 

.visible .entry _Z2f1i(
     .param .u32 _Z2f1i_param_0 
) 
{ 
     .reg .pred  %p<2>; 
     .reg .b32  %r<10>; 


     ld.param.u32 %r9, [_Z2f1i_param_0]; 

BB0_1: 
     mov.u32   %r1, %r9; 
     mul.hi.s32  %r4, %r1, 715827883; 
     shr.u32   %r5, %r4, 31; 
     add.s32   %r6, %r4, %r5; 
     mul.lo.s32  %r7, %r6, 6; 
     sub.s32   %r8, %r1, %r7; 
     add.s32   %r9, %r1, 1; 
     setp.ne.s32  %p1, %r8, 0; 
     @%p1 bra  BB0_1; 

     st.global.u32 [i], %r1; 
     ret; 
} 

從nvdisasm的cubin:

//--------------------- .text._Z2f1i    -------------------------- 
     .section  .text._Z2f1i,"ax",@progbits 
     .sectioninfo @"SHI_REGISTERS=6" 
     .align 4 
     .global   _Z2f1i 
     .type   _Z2f1i,@function 
     .size   _Z2f1i,(.L_13 - _Z2f1i) 
     .other   _Z2f1i,@"STO_CUDA_ENTRY STV_DEFAULT" 
_Z2f1i: 
.text._Z2f1i: 
     /*0000*/   MOV R1, c[0x1][0x100]; 
     /*0008*/   MOV R0, c[0x0][0x20]; 
     /*0010*/   NOP; 
     /*0018*/   NOP; 
     /*0020*/   NOP; 
     /*0028*/   NOP; 
     /*0030*/   NOP; 
     /*0038*/   NOP; 
.L_2: 
     /*0040*/   IMUL.HI R2, R0, c[0x10][0x0]; 
     /*0048*/   IMAD.U32.U32.HI R2, R2, 0x2, R2; 
     /*0050*/   IMAD R2, -R2, 0x6, R0; 
     /*0058*/   ISETP.NE.AND P0, PT, R2, RZ, PT; 
     /*0060*/   MOV R2, R0; 
     /*0068*/   IADD R0, R0, 0x1; 
     /*0070*/  @P0 BRA `(.L_2); 
     /*0078*/   MOV R4, c[0xe][0x0]; 
     /*0080*/   MOV R5, c[0xe][0x4]; 
     /*0088*/   ST.E [R4], R2; 
     /*0090*/   EXIT; 
.L_13: 

在這兩種情況下都有預測分支,但沒有調用。

+0

通常我upvote對我的問題的答覆所以,但我覺得這裏的長答案太懶惰。即使你是對的,我至少希望看到一個尾遞歸循環,而不是在主體中只調用一次的函數。就你的例子而言,即使沒有TCO,我也希望它內聯。 –

+0

對於尾遞歸循環,可能會在打印語句中確認編譯器沒有優化功能。 –

+0

你說得對,這不是尾遞歸。你能證實這個例子是否更好? – vguberinic