我正在處理一個結構數組,我希望每個塊都可以在共享內存中加載數組的一個單元。例如:塊0將在共享內存中加載數組[0],塊1將加載數組[1]。CUDA合併內存加載行爲
爲了做到這一點,我使用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毫秒
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毫秒
在這兩個版本我使用了NVIDIA探查和全局負載效率爲8%。
我有兩個問題: 1 - 我不明白爲什麼有時間差異。 2 - 我的電話是否合併?
我使用2.1計算能力(32線/套)
編譯器可能會在消除無用代碼的意義上進行優化。因此,由於你的線程實際上對全局內存沒有影響,所以編譯器可以消除代碼,並且在第二次執行四倍多的線程時,你可以獲得應用程序。計算時間的四倍。檢查編譯器的ptx-output以確認我的假設。 – stuhlo 2013-03-25 21:19:37