使用make_int3 vs直接分配值

时间:2015-06-05 08:20:07

标签: cuda parallel-processing

我需要在cuda内核中为int3(比如p)类型的变量赋值。分配在内核中完成了~10次。

int3 p;
p = make_int3(a,b,c);

int3 p;
p.x = a; p.y = b; p.z = c;

上述哪种方式会更好,或者两者在速度方面都有相同的效果?

我在某处读到(不记得源代码)make_int3是一种构造函数,所以直接初始化值会更好吗?

1 个答案:

答案 0 :(得分:1)

您可以使用以下代码和nvvp对差异进行基准测试。

#include "cuda_runtime.h"

__global__
void assign_int3(int3* ptr)
{
    int offset = threadIdx.x+blockIdx.x*blockDim.x;
    int3 value = {0};
    for(int i=0;i<10;i++)
    {
        value = make_int3(i, i*2, i*3);
    }
    ptr[offset] = value;
}

__global__
void assign_values(int3* ptr)
{
    int offset = threadIdx.x+blockIdx.x*blockDim.x;
    int3 value = {0};
    for(int i=0;i<10;i++)
    {
        value.x=i;
        value.y=i*2;
        value.z=i*3;
    }
    ptr[offset]=value;
}

int main()
{
    int3* ptr;
    cudaMalloc(&ptr, 64*1024*sizeof(int3));
    assign_int3<<<1024, 64>>>(ptr);
    assign_values<<<1024, 64>>>(ptr);

    cudaDeviceSynchronize();
    cudaFree(ptr);
}

生成的ptx代码是相同的,因此没有任何差异,因为make_int *方法是内联的。

.visible .entry _Z11assign_int3P4int3(
    .param .u64 _Z11assign_int3P4int3_param_0
)
{
    .reg .s32       %r<8>;
    .reg .s64       %rd<5>;


    ld.param.u64    %rd1, [_Z11assign_int3P4int3_param_0];
    cvta.to.global.u64      %rd2, %rd1;
    mov.u32         %r1, %tid.x;
    mov.u32         %r2, %ctaid.x;
    mov.u32         %r3, %ntid.x;
    mad.lo.s32      %r4, %r3, %r2, %r1;
    mul.wide.s32    %rd3, %r4, 12;
    add.s64         %rd4, %rd2, %rd3;
    mov.u32         %r5, 27;
    st.global.u32   [%rd4+8], %r5;
    mov.u32         %r6, 18;
    st.global.u32   [%rd4+4], %r6;
    mov.u32         %r7, 9;
    st.global.u32   [%rd4], %r7;
    ret;
}

.visible .entry _Z13assign_valuesP4int3(
    .param .u64 _Z13assign_valuesP4int3_param_0
)
{
    .reg .s32       %r<8>;
    .reg .s64       %rd<5>;


    ld.param.u64    %rd1, [_Z13assign_valuesP4int3_param_0];
    cvta.to.global.u64      %rd2, %rd1;
    mov.u32         %r1, %tid.x;
    mov.u32         %r2, %ctaid.x;
    mov.u32         %r3, %ntid.x;
    mad.lo.s32      %r4, %r3, %r2, %r1;
    mul.wide.s32    %rd3, %r4, 12;
    add.s64         %rd4, %rd2, %rd3;
    mov.u32         %r5, 27;
    st.global.u32   [%rd4+8], %r5;
    mov.u32         %r6, 18;
    st.global.u32   [%rd4+4], %r6;
    mov.u32         %r7, 9;
    st.global.u32   [%rd4], %r7;
    ret;
}