cuda内核 - 寄存器

时间:2011-08-20 15:54:07

标签: cuda

内核中定义的Float4变量应存储在寄存器中!我做了一个简单的测试。在第一个内核中,我使用寄存器来优化内存流量,第二个内核直接从全局内存中读取。

__global__ void kernel(float4 *arg1, float4 *arg2, float4 *arg3)
{
     int x = blockIdx.x * blockDim.x + threadIdx.x;

     float4 temp1 = arg2[x];
     float4 temp2 = arg3[x];
     //some computations using temp1 and temp2
     arg2[x] = temp1;
     arg3[x] = temp2;

     arg1[x] = make_float4(temp1.x, temp1.y, temp1.z, temp1.w);
}



 __global__ void kernel(float4 *arg1, float4 *arg2, float4 *arg3)
{
     int x = blockIdx.x * blockDim.x + threadIdx.x;
     //some computations using a direct access to global memory
     //for example arg2[x].x
     arg1[x] = make_float4(arg2[x].x, arg2[x].y, arg2[x].z, arg2[x].w);
}

第一个内核的速度提高了9-10%。差别不大。使用寄存器时可以带来更多好处吗?

1 个答案:

答案 0 :(得分:2)

首先,你不能说仅仅基于C代码的寄存器是什么,不会是什么。这肯定不是两个代码之间性能差异的来源。事实上,两个内核都使用寄存器来处理float4变量,它们编译的代码几乎相同。

第一个内核:

ld.param.u64    %rd3, [__cudaparm__Z7kernel0P6float4S0_S0__arg2];
add.u64         %rd4, %rd3, %rd2;
ld.global.v4.f32        {%f1,%f2,%f3,%f4}, [%rd4+0];
.loc    16      21      0
ld.param.u64    %rd5, [__cudaparm__Z7kernel0P6float4S0_S0__arg3];
add.u64         %rd6, %rd5, %rd2;
ld.global.v4.f32        {%f5,%f6,%f7,%f8}, [%rd6+0];
st.global.v4.f32        [%rd4+0], {%f1,%f2,%f3,%f4};
st.global.v4.f32        [%rd6+0], {%f5,%f6,%f7,%f8};
.loc    16      24      0
ld.param.u64    %rd7, [__cudaparm__Z7kernel0P6float4S0_S0__arg1];
add.u64         %rd8, %rd7, %rd2;
st.global.v4.f32        [%rd8+0], {%f1,%f2,%f3,%f4};

第二个内核:

ld.param.u64    %rd3, [__cudaparm__Z7kernel1P6float4S0_S0__arg2];
add.u64         %rd4, %rd3, %rd2;
ld.global.v4.f32        {%f1,%f2,%f3,%f4}, [%rd4+0];
ld.param.u64    %rd5, [__cudaparm__Z7kernel1P6float4S0_S0__arg1];
add.u64         %rd6, %rd5, %rd2;
st.global.v4.f32        [%rd6+0], {%f1,%f2,%f3,%f4};

如果它们之间确实存在性能差异,那么第一个内核可能比第二个内核具有更多的指令级并行机会。但这只是一个疯狂的猜测,不知道更多关于如何完成两者的基准测试。