Performance 如何在CUDA中不使用原子进行求和计算
在下面的代码中,如何在不使用atomicAdd的情况下计算sum\u array值 核方法Performance 如何在CUDA中不使用原子进行求和计算,performance,optimization,cuda,sum,Performance,Optimization,Cuda,Sum,在下面的代码中,如何在不使用atomicAdd的情况下计算sum\u array值 核方法 __global__ void calculate_sum( int width, int height, int *pntrs, int2 *sum_array ) { int row = blockIdx.y
__global__ void calculate_sum( int width,
int height,
int *pntrs,
int2 *sum_array )
{
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if ( row >= height || col >= width ) return;
int idx = pntrs[ row * width + col ];
//atomicAdd( &sum_array[ idx ].x, col );
//atomicAdd( &sum_array[ idx ].y, row );
sum_array[ idx ].x += col;
sum_array[ idx ].y += row;
}
启动内核
dim3 dimBlock( 16, 16 );
dim3 dimGrid( ( width + ( dimBlock.x - 1 ) ) / dimBlock.x,
( height + ( dimBlock.y - 1 ) ) / dimBlock.y );
归约是这类问题的总称。进一步解释,请参阅,其他示例请使用谷歌 解决这个问题的一般方法是在线程块内对全局内存段进行并行求和,并将结果存储在全局内存中。然后,将部分结果复制到CPU内存空间,使用CPU对部分结果求和,然后将结果复制回GPU内存。您可以通过对部分结果执行另一个并行求和来避免内存占用
另一种方法是为CUDA使用高度优化的库,如推力或CUDPP,其中包含执行这些操作的函数。缩减是此类问题的通用名称。进一步解释,请参阅,其他示例请使用谷歌 解决这个问题的一般方法是在线程块内对全局内存段进行并行求和,并将结果存储在全局内存中。然后,将部分结果复制到CPU内存空间,使用CPU对部分结果求和,然后将结果复制回GPU内存。您可以通过对部分结果执行另一个并行求和来避免内存占用 另一种方法是为CUDA使用高度优化的库,如包含函数的推力或CUDPP。我的CUDA非常生锈,但大致上就是这样做的(由“CUDA示例”提供,我强烈建议您阅读):
//在片上求和的代码,本质上是每个线程子集上的循环
//并在“localsum”(局部变量)上累加
...
//将结果保存在共享内存中
部分[threadidx]=localsum;
//同步线程:
__同步线程();
//从现在起,所有计算的结果都将填入partial:您可以减少partial
//我们将以不识字的方式,使用一个线程(它可以很容易地并行化)
如果(threadidx==0){
对于(i=1;i
然后你离开:部分[0]将保留你的总和(或计算)
请参阅“CUDA by example”中的点积示例,以了解有关该主题的更严格的讨论以及大约在O(log(n))中运行的简化算法
希望这有帮助我的Cuda非常生锈,但这大致就是你如何做到的(由“Cuda举例”提供,我强烈建议你阅读):
//在片上求和的代码,本质上是每个线程子集上的循环
//并在“localsum”(局部变量)上累加
...
//将结果保存在共享内存中
部分[threadidx]=localsum;
//同步线程:
__同步线程();
//从现在起,所有计算的结果都将填入partial:您可以减少partial
//我们将以不识字的方式,使用一个线程(它可以很容易地并行化)
如果(threadidx==0){
对于(i=1;i
然后你离开:部分[0]将保留你的总和(或计算)
请参阅“CUDA by example”中的点积示例,以了解有关该主题的更严格的讨论以及大约在O(log(n))中运行的简化算法
希望这有帮助
// Code to sum over a slice, essentially a loop over each thread subset
// and accumulate over "localsum" (a local variable)
...
// Save the result in the shared memory
partial[threadidx] = localsum;
// Synchronize the threads:
__syncthreads();
// From now on partial is filled with the result of all computations: you can reduce partial
// we'll do it the illiterate way, using a single thread (it can be easily parallelized)
if(threadidx == 0) {
for(i = 1; i < nthreads; ++i) {
partial[0] += partial[i];
}
}