我正在使用一个结构数组,并且我希望每个块都将共享内存加载到数组的一个单元格中。例如:块 0 将在共享内存中加载数组 [0],块 1 将加载数组 [1]。
为了做到这一点,我将结构数组转换为 float* 以尝试合并内存访问。
我有两个版本的代码
版本 1
__global__
void load_structure(float * label){
__shared__ float shared_label[48*16];
__shared__ struct LABEL_2D* self_label;
shared_label[threadIdx.x*16+threadIdx.y] =
label[blockIdx.x*sizeof(struct LABEL_2D)/sizeof(float) +threadIdx.x*16+threadIdx.y];
shared_label[(threadIdx.x+16)*16+threadIdx.y] =
label[blockIdx.x*sizeof(struct LABEL_2D)/sizeof(float) + (threadIdx.x+16)*16+threadIdx.y];
if((threadIdx.x+32)*16+threadIdx.y < sizeof(struct LABEL_2D)/sizeof(float)) {
shared_label[(threadIdx.x+32)*16+threadIdx.y] =
label[blockIdx.x*sizeof(struct LABEL_2D)/sizeof(float) +(threadIdx.x+32)*16+threadIdx.y];
}
if(threadIdx.x == 0){
self_label = (struct LABEL_2D *) shared_label;
}
__syncthreads();
return;
}
...
dim3 dimBlock(16,16);
load_structure<<<2000,dimBlock>>>((float*)d_Label;
计算时间:0.740032 ms
版本 2
__global__
void load_structure(float * label){
__shared__ float shared_label[32*32];
__shared__ struct LABEL_2D* self_label;
if(threadIdx.x*32+threadIdx.y < *sizeof(struct LABEL_2D)/sizeof(float))
shared_label[threadIdx.x*32+threadIdx.y] =
label[blockIdx.x*sizeof(struct LABEL_2D)/sizeof(float)+threadIdx.x*32+threadIdx.y+];
if(threadIdx.x == 0){
self_label = (struct LABEL_2D *) shared_label;
}
__syncthreads();
return;
}
dim3 dimBlock(32,32);
load_structure<<<2000,dimBlock>>>((float*)d_Label);
计算时间:2.559264 ms
在这两个版本中,我都使用了 nvidia 分析器,全局负载效率为 8%。
我有两个问题: 1 - 我不明白为什么会有时间差异。2 - 我的通话是否合并?
我正在使用具有 2.1 计算能力的视频卡(32 线程/环绕)