【发布时间】:2012-05-03 01:19:42
【问题描述】:
我正在尝试利用此内核函数中的共享内存,但性能不如我预期的那么好。这个函数在我的应用程序中被调用了很多次(大约 1000 次或更多),所以我想利用共享内存来避免内存延迟。但显然有些问题是因为我使用共享内存后我的应用程序变得非常慢。
这是内核:
__global__ void AndBitwiseOperation(int* _memory_device, int b1_size, int* b1_memory, int* b2_memory){
int j = 0;
// index GPU - Transaction-wise
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int tid = threadIdx.x;
// shared variable
extern __shared__ int shared_memory_data[];
extern __shared__ int shared_b1_data[];
extern __shared__ int shared_b2_data[];
// copy from global memory into shared memory and sync threads
shared_b1_data[tid] = b1_memory[tid];
shared_b2_data[tid] = b2_memory[tid];
__syncthreads();
// AND each int bitwise
for(j = 0; j < b1_size; j++)
shared_memory_data[tid] = (shared_b1_data[tid] & shared_b2_data[tid]);
// write result for this block to global memory
_memory_device[i] = shared_memory_data[i];
}
共享变量被声明为 extern 因为我不知道 b1 和 b2 的大小,因为它们取决于我只能在运行时知道的客户数量(但两者的大小相同一直)。
这就是我调用内核的方式:
void Bitmap::And(const Bitmap &b1, const Bitmap &b2)
{
int* _memory_device;
int* b1_memory;
int* b2_memory;
int b1_size = b1.getIntSize();
// allocate memory on GPU
(cudaMalloc((void **)&b1_memory, _memSizeInt * SIZE_UINT));
(cudaMalloc((void **)&b2_memory, _memSizeInt * SIZE_UINT));
(cudaMalloc((void **)&_memory_device, _memSizeInt * SIZE_UINT));
// copy values on GPU
(cudaMemcpy(b1_memory, b1._memory, _memSizeInt * SIZE_UINT, cudaMemcpyHostToDevice ));
(cudaMemcpy(b2_memory, b2._memory, _memSizeInt * SIZE_UINT, cudaMemcpyHostToDevice ));
(cudaMemcpy(_memory_device, _memory, _memSizeInt * SIZE_UINT, cudaMemcpyHostToDevice ));
dim3 dimBlock(1, 1);
dim3 dimGrid(1, 1);
AndBitwiseOperation<<<dimGrid, dimBlock>>>(_memory_device, b1_size, b1_memory, b2_memory);
// return values
(cudaMemcpy(_memory, _memory_device, _memSizeInt * SIZE_UINT, cudaMemcpyDeviceToHost ));
// Free Memory
(cudaFree(b1_memory));
(cudaFree(b2_memory));
(cudaFree(_memory_device));
}
b1 和 b2 是位图,每个元素有 4 位。元素的数量取决于客户的数量。另外,我对内核的参数有疑问,因为如果我添加一些块或线程,AndBitwiseOperation() 不会给我正确的结果。每个块只有 1 个块和 1 个线程,结果是正确的,但内核不是并行的。
欢迎每一个建议:)
谢谢
【问题讨论】:
-
你说你使用这个函数+1000次(在一分钟?秒?小时?)我建议对这个特定函数进行内联编译,这将大大提高性能
-
您的循环在每次迭代中执行完全相同的计算,并覆盖结果。在这种情况下,您不需要共享内存,因为您没有使用它在线程之间共享数据或以任何方式优化内存访问顺序。
标签: cuda parallel-processing shared-memory