我有一个复数数据大小为NxN的矩阵u,我希望将每行元素乘以一个大小为1xN的向量k。 u中的数据按行存储。
我有两个这样的实现。一个利用共享内存,将矩阵划分为瓦片,另一个不分块。
我发现共享内存实现multiply1并不快,并且系统性地与multiply2一样快,甚至更慢。
共享内存实现如下,
__global__ void multiply1(cufftComplex *u, cufftComplex *k) {
__shared__ cufftComplex k_s[BLOCK_WIDTH];
int idx = blockDim.x*blockIdx.x + threadIdx.x;
int idy = blockDim.y*blockIdx.y + threadIdx.y;
int index;
if (threadIdx.y == 0 && idx < N) {
k_s[threadIdx.x] = k[idx];
}
__syncthreads();
if (idx < N && idy < N) {
index = N*idy + idx;
u[index] = cuCmulf(k_s[threadIdx.x],u[index]);
}
}
全局内存实现如下,
__global__ void multiply2(cufftComplex *u, cufftComplex *k) {
int idx = blockDim.x * blockIdx.x + threadIdx.x;
if (idx < N*N) {
u[idx] =cuCmulf(k[idx % N],u[idx]);
}
}
和主函数调用,对于大小为64x64的矩阵
dim3 block(16,16);
dim3 grid(4,4);
multiply1<<<grid, block>>>(d_u, d_k);
multiply2<<<16, 256>>>(d_u, d_k);
如何使用分析器找出为什么multiply1在速度上几乎没有轻微增加?哪些指标可以阐明究竟发生了什么?
分析器告诉我,对于multiply1,我得到152 GB / s的全局内存负载吞吐量,而对于multiply2,我得到81 GB / s。这是合乎逻辑的,因为我从全局内存加载较少。难道这不能转化为更快的执行吗?
答案 0 :(得分:1)
如果你多次使用它会更快但在这里你只使用它一次。你改变了你的问题:
copy from global memory to shared memory
read from shared memory
而不是:
read from global memory
所以是的,它肯定比仅使用全局内存的前一算法慢。如果你想利用共享内存,你的算法要多次读取,否则你不会开销全局内存。