Cuda 如何在寄存器中强制var4。

Cuda 如何在寄存器中强制var4。,cuda,Cuda,我有以下代表代码: __global__ void func() { register ushort4 result = make_ushort4(__float2half_rn(0.5), __float2half_rn(0.5), __float2half_rn(0.5), __float2half_rn(1.0)); } 编译时,结果存储在本地内存中。是否可以将此强制到注册表?本地内存对于预期的应用程序来说太慢 此外,此结果必须存储到var4元素的数组中。我希望合并存储这些结果,

我有以下代表代码:

__global__ void func()
{
    register ushort4 result = make_ushort4(__float2half_rn(0.5), __float2half_rn(0.5), __float2half_rn(0.5), __float2half_rn(1.0));
}
编译时,
结果
存储在本地内存中。是否可以将此强制到注册表?本地内存对于预期的应用程序来说太慢


此外,此结果必须存储到var4元素的数组中。我希望合并存储这些结果,比如
((ushort4*)(output))[x+y*width]=result。另一个没有var4的解决方案也是一个选项

如果有可用寄存器,则应将向量类型编译到寄存器中。将您的代码片段转化为能够在死代码删除后存活下来的内容:

__global__ void func(ushort4 *out) 
{ 
    ushort4 result = make_ushort4(__float2half_rn(0.5), __float2half_rn(0.5), 
            __float2half_rn(0.5), __float2half_rn(1.0)); 

    out[threadIdx.x+blockDim.x*blockIdx.x] = result;
} 
并编制:

>nvcc -cubin -arch=sm_20 -Xptxas="-v" ushort4.cu
ushort4.cu
ushort4.cu
tmpxft_000010b8_00000000-3_ushort4.cudafe1.gpu
tmpxft_000010b8_00000000-10_ushort4.cudafe2.gpu
ptxas info    : Compiling entry function '_Z4funcP7ushort4' for 'sm_20'
ptxas info    : Function properties for _Z4funcP7ushort4
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 8 registers, 36 bytes cmem[0]
显示无溢出(即本地内存)。此外,分解生成的cubin文件显示:

>cuobjdump --dump-sass ushort4.cubin

        code for sm_20
                Function : _Z4funcP7ushort4
        /*0000*/     /*0x00005de428004404*/     MOV R1, c [0x1] [0x100];
        /*0008*/     /*0x01101c041000cfc0*/     F2F.F16.F32 R0, 0x3f000;
        /*0010*/     /*0x94009c042c000000*/     S2R R2, SR_CTAid_X;
        /*0018*/     /*0x8400dc042c000000*/     S2R R3, SR_Tid_X;
        /*0020*/     /*0x01111c041000cfe0*/     F2F.F16.F32 R4, 0x3f800;
        /*0028*/     /*0x00915c041c000000*/     I2I.U16.U16 R5, R0;
        /*0030*/     /*0x20209c0320064000*/     IMAD.U32.U32 R2, R2, c [0x0] [0x8], R3;
        /*0038*/     /*0x40019c03280ac040*/     BFI R6, R0, 0x1010, R5;
        /*0040*/     /*0x4041dc03280ac040*/     BFI R7, R4, 0x1010, R5;
        /*0048*/     /*0x80201c6340004000*/     ISCADD R0, R2, c [0x0] [0x20], 0x3;
        /*0050*/     /*0x00019ca590000000*/     ST.64 [R0], R6;
        /*0058*/     /*0x00001de780000000*/     EXIT;
                .................................
即,
ushort4
被填充到寄存器中,然后使用64位存储将压缩向量写入全局内存。无法看到本地内存访问

因此,如果您确信有一个向量值正在编译到本地内存中,这可能是因为您有一个具有大量寄存器压力的内核,或者您正在要求编译器(volatile关键字可以做到这一点),或者您误解了编译器/汇编程序在编译时告诉您的内容


编辑:将CUDA 4.0发行版tookit与Visual Studio Express 2008配合使用,并在32位Windows 7上编译compute 1.1设备,可提供:

>nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2011 NVIDIA Corporation
Built on Fri_May_13_02:42:40_PDT_2011
Cuda compilation tools, release 4.0, V0.2.1221

>cl.exe
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]


>nvcc -cubin -arch=sm_11 -Xptxas=-v ushort4.cu
ushort4.cu
ushort4.cu
tmpxft_00001788_00000000-3_ushort4.cudafe1.gpu
tmpxft_00001788_00000000-10_ushort4.cudafe2.gpu
ptxas info    : Compiling entry function '_Z4funcP7ushort4' for 'sm_11'
ptxas info    : Used 4 registers, 4+16 bytes smem

这与compute 2.0目标的原始构建结果完全相同。

如果有可用的寄存器,则应将向量类型编译到寄存器中。将您的代码片段转化为能够在死代码删除后存活下来的内容:

__global__ void func(ushort4 *out) 
{ 
    ushort4 result = make_ushort4(__float2half_rn(0.5), __float2half_rn(0.5), 
            __float2half_rn(0.5), __float2half_rn(1.0)); 

    out[threadIdx.x+blockDim.x*blockIdx.x] = result;
} 
并编制:

>nvcc -cubin -arch=sm_20 -Xptxas="-v" ushort4.cu
ushort4.cu
ushort4.cu
tmpxft_000010b8_00000000-3_ushort4.cudafe1.gpu
tmpxft_000010b8_00000000-10_ushort4.cudafe2.gpu
ptxas info    : Compiling entry function '_Z4funcP7ushort4' for 'sm_20'
ptxas info    : Function properties for _Z4funcP7ushort4
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 8 registers, 36 bytes cmem[0]
显示无溢出(即本地内存)。此外,分解生成的cubin文件显示:

>cuobjdump --dump-sass ushort4.cubin

        code for sm_20
                Function : _Z4funcP7ushort4
        /*0000*/     /*0x00005de428004404*/     MOV R1, c [0x1] [0x100];
        /*0008*/     /*0x01101c041000cfc0*/     F2F.F16.F32 R0, 0x3f000;
        /*0010*/     /*0x94009c042c000000*/     S2R R2, SR_CTAid_X;
        /*0018*/     /*0x8400dc042c000000*/     S2R R3, SR_Tid_X;
        /*0020*/     /*0x01111c041000cfe0*/     F2F.F16.F32 R4, 0x3f800;
        /*0028*/     /*0x00915c041c000000*/     I2I.U16.U16 R5, R0;
        /*0030*/     /*0x20209c0320064000*/     IMAD.U32.U32 R2, R2, c [0x0] [0x8], R3;
        /*0038*/     /*0x40019c03280ac040*/     BFI R6, R0, 0x1010, R5;
        /*0040*/     /*0x4041dc03280ac040*/     BFI R7, R4, 0x1010, R5;
        /*0048*/     /*0x80201c6340004000*/     ISCADD R0, R2, c [0x0] [0x20], 0x3;
        /*0050*/     /*0x00019ca590000000*/     ST.64 [R0], R6;
        /*0058*/     /*0x00001de780000000*/     EXIT;
                .................................
即,
ushort4
被填充到寄存器中,然后使用64位存储将压缩向量写入全局内存。无法看到本地内存访问

因此,如果您确信有一个向量值正在编译到本地内存中,这可能是因为您有一个具有大量寄存器压力的内核,或者您正在要求编译器(volatile关键字可以做到这一点),或者您误解了编译器/汇编程序在编译时告诉您的内容


编辑:将CUDA 4.0发行版tookit与Visual Studio Express 2008配合使用,并在32位Windows 7上编译compute 1.1设备,可提供:

>nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2011 NVIDIA Corporation
Built on Fri_May_13_02:42:40_PDT_2011
Cuda compilation tools, release 4.0, V0.2.1221

>cl.exe
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]


>nvcc -cubin -arch=sm_11 -Xptxas=-v ushort4.cu
ushort4.cu
ushort4.cu
tmpxft_00001788_00000000-3_ushort4.cudafe1.gpu
tmpxft_00001788_00000000-10_ushort4.cudafe2.gpu
ptxas info    : Compiling entry function '_Z4funcP7ushort4' for 'sm_11'
ptxas info    : Used 4 registers, 4+16 bytes smem

这与compute 2.0目标的原始版本的结果完全相同。

这是您建议的函数的结果:
2>ptxas info:sm 11'2>ptxas info:8个寄存器,32+0字节lmem,16+16字节smem,4字节cmem[1]的编译输入函数“Z4funcP7ushort4”
。此外,我必须使用sm11。@Patrik:这是什么编译器版本和操作系统?我已经用Cuda 3.2和4.0为sm11、sm12和sm20编译了这篇文章。所有代码都只使用寄存器发出;nvcc版本4.0,V0.2.1221;选项=--gpu架构=sm_11--ptxas选项=-v;os=vista@帕特里克:对不起,但我无法复制。查看编辑。@talonmier谢谢你的帮助,我会在另一台计算机上做更多的测试。至少现在我知道它应该可以工作了。这是您建议的函数的结果:
2>ptxas info:sm\u 11'2>ptxas info:8个寄存器,32+0字节lmem,16+16字节smem,4字节cmem[1]
。此外,我必须使用sm11。@Patrik:这是什么编译器版本和操作系统?我已经用Cuda 3.2和4.0为sm11、sm12和sm20编译了这篇文章。所有代码都只使用寄存器发出;nvcc版本4.0,V0.2.1221;选项=--gpu架构=sm_11--ptxas选项=-v;os=vista@帕特里克:对不起,但我无法复制。查看编辑。@talonmier谢谢你的帮助,我会在另一台计算机上做更多的测试。至少现在我知道它应该起作用了。