我需要在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是一种构造函数,所以直接初始化值会更好吗?
答案 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;
}