CUDA';s memcpy(dst,src,0)写入*dst?

CUDA';s memcpy(dst,src,0)写入*dst?,cuda,memcpy,invalid-argument,Cuda,Memcpy,Invalid Argument,我有一些内核代码调用memcpy(my_dst,my_src,my_num_bytes)——有时我的my_num_bytes等于0。奇怪的是,一些零星的实验(使用Titan X、CUDA 7.5、driver 358.16)表明,当我使用这种呼叫时,数据确实会写入目的地 您在CUDA中遇到过这种行为吗 这是指定的地方吗?memcpy()的编程指南条目 这似乎是设备端memcpy()的(当前,即CUDA 7.5)实现中的一个错误 这样的内核: __global__ void kernel(char

我有一些内核代码调用
memcpy(my_dst,my_src,my_num_bytes)
——有时我的
my_num_bytes
等于0。奇怪的是,一些零星的实验(使用Titan X、CUDA 7.5、driver 358.16)表明,当我使用这种呼叫时,数据确实会写入目的地

  • 您在CUDA中遇到过这种行为吗
  • 这是指定的地方吗?
    memcpy()
    的编程指南条目

  • 这似乎是设备端
    memcpy()
    的(当前,即CUDA 7.5)实现中的一个错误

    这样的内核:

    __global__ void kernel(char* source, char* dst, int len, int sz)
    {
    
        int i = threadIdx.x * len;
    
        memcpy(source+i, dst+i, sz);
    }
    
            // .globl       _Z6kernelPcS_ii
    .visible .entry _Z6kernelPcS_ii(
            .param .u64 _Z6kernelPcS_ii_param_0,
            .param .u64 _Z6kernelPcS_ii_param_1,
            .param .u32 _Z6kernelPcS_ii_param_2,
            .param .u32 _Z6kernelPcS_ii_param_3
    )
    {
            .reg .pred      %p<2>;
            .reg .b16       %rs<2>;
            .reg .b32       %r<4>;
            .reg .b64       %rd<15>;
    
    
            ld.param.u64    %rd7, [_Z6kernelPcS_ii_param_0];
            ld.param.u64    %rd8, [_Z6kernelPcS_ii_param_1];
            ld.param.u32    %r1, [_Z6kernelPcS_ii_param_2];
            cvta.to.global.u64      %rd9, %rd8;
            cvta.to.global.u64      %rd10, %rd7;
            mov.u32         %r2, %tid.x;
            mul.lo.s32      %r3, %r2, %r1;
            cvt.s64.s32     %rd11, %r3;
            add.s64         %rd1, %rd10, %rd11;
            add.s64         %rd2, %rd9, %rd11;
            mov.u64         %rd14, 0;
            ld.param.s32    %rd3, [_Z6kernelPcS_ii_param_3];
    
    BB6_1:
            add.s64         %rd12, %rd2, %rd14;
            ld.global.u8    %rs1, [%rd12];
            add.s64         %rd13, %rd1, %rd14;
            st.global.u8    [%rd13], %rs1;
            add.s64         %rd14, %rd14, 1;
            setp.lt.u64     %p1, %rd14, %rd3;
            @%p1 bra        BB6_1;
    
            ret;
    }
    
    BB6_1:
            setp.ge.u64     %p1, %rd14, %rd3;
            @%p1 bra        Done;
            add.s64         %rd12, %rd2, %rd14;
            ld.global.u8    %rs1, [%rd12];
            add.s64         %rd13, %rd1, %rd14;
            st.global.u8    [%rd13], %rs1;
            add.s64         %rd14, %rd14, 1;
            bra             BB6_1;
    Done:
    
    引导工具链发出PTX,如下所示:

    __global__ void kernel(char* source, char* dst, int len, int sz)
    {
    
        int i = threadIdx.x * len;
    
        memcpy(source+i, dst+i, sz);
    }
    
            // .globl       _Z6kernelPcS_ii
    .visible .entry _Z6kernelPcS_ii(
            .param .u64 _Z6kernelPcS_ii_param_0,
            .param .u64 _Z6kernelPcS_ii_param_1,
            .param .u32 _Z6kernelPcS_ii_param_2,
            .param .u32 _Z6kernelPcS_ii_param_3
    )
    {
            .reg .pred      %p<2>;
            .reg .b16       %rs<2>;
            .reg .b32       %r<4>;
            .reg .b64       %rd<15>;
    
    
            ld.param.u64    %rd7, [_Z6kernelPcS_ii_param_0];
            ld.param.u64    %rd8, [_Z6kernelPcS_ii_param_1];
            ld.param.u32    %r1, [_Z6kernelPcS_ii_param_2];
            cvta.to.global.u64      %rd9, %rd8;
            cvta.to.global.u64      %rd10, %rd7;
            mov.u32         %r2, %tid.x;
            mul.lo.s32      %r3, %r2, %r1;
            cvt.s64.s32     %rd11, %r3;
            add.s64         %rd1, %rd10, %rd11;
            add.s64         %rd2, %rd9, %rd11;
            mov.u64         %rd14, 0;
            ld.param.s32    %rd3, [_Z6kernelPcS_ii_param_3];
    
    BB6_1:
            add.s64         %rd12, %rd2, %rd14;
            ld.global.u8    %rs1, [%rd12];
            add.s64         %rd13, %rd1, %rd14;
            st.global.u8    [%rd13], %rs1;
            add.s64         %rd14, %rd14, 1;
            setp.lt.u64     %p1, %rd14, %rd3;
            @%p1 bra        BB6_1;
    
            ret;
    }
    
    BB6_1:
            setp.ge.u64     %p1, %rd14, %rd3;
            @%p1 bra        Done;
            add.s64         %rd12, %rd2, %rd14;
            ld.global.u8    %rs1, [%rd12];
            add.s64         %rd13, %rd1, %rd14;
            st.global.u8    [%rd13], %rs1;
            add.s64         %rd14, %rd14, 1;
            bra             BB6_1;
    Done:
    

    可能会像预期的那样工作。

    请参阅:根据我的测试,这似乎在CUDA 8RC中得到了修复