Cuda 在不使用共享内存的情况下执行矩阵元素径向平均的有效方法

Cuda 在不使用共享内存的情况下执行矩阵元素径向平均的有效方法,cuda,gpgpu,gpuimage,gpu,jcuda,Cuda,Gpgpu,Gpuimage,Gpu,Jcuda,我试图在CUDA中实现矩阵元素的径向平均,在这里我必须找到并打印每个矩阵元素的所有相邻元素(包括其本身)的平均值。以下是我得到的结果(对于半径=1): 我上面的代码检查顶行、底行、最右边和最左边的列元素的条件,它必须计算6个元素的平均值。Ans也适用于4个角元素,它必须计算4个元素的平均值。对于剩余的内部元素,必须计算9个元素的平均值。 上面的代码只是一个简单的C到CUDA的转换程序。我正在寻找一种最有效的方法,不使用共享内存来编写任何给定半径的程序。 任何算法、伪代码或建议都可以。提前谢谢 这

我试图在CUDA中实现矩阵元素的径向平均,在这里我必须找到并打印每个矩阵元素的所有相邻元素(包括其本身)的平均值。以下是我得到的结果(对于半径=1):

我上面的代码检查顶行、底行、最右边和最左边的列元素的条件,它必须计算6个元素的平均值。Ans也适用于4个角元素,它必须计算4个元素的平均值。对于剩余的内部元素,必须计算9个元素的平均值。 上面的代码只是一个简单的C到CUDA的转换程序。我正在寻找一种最有效的方法,不使用共享内存来编写任何给定半径的程序。
任何算法、伪代码或建议都可以。提前谢谢

这就是我在不使用共享内存的情况下实现矩阵元素径向平均的方法:

__global__ void matrix_avg(float *ad,float *bd, int radius, int N)
{
    int counter =0,i,j;
    float sum=0.0;

    int globalRow = blockIdx.y * blockDim.y + threadIdx.y;
    int globalCol = blockIdx.x * blockDim.x + threadIdx.x;

    for(i=-radius;i<=radius;i++)
    {
        for(j=-radius;j<=radius;j++)
        {
            if(((globalRow+i)<0) || ((globalCol+j)<0) || ((globalRow+i)>=N) || ((globalCol+j)>=N))
            {
                sum = sum + 0;
            }
            else
            {
                sum = sum + ad[(globalRow+i)*N+(globalCol+j)];
                counter++;
            }
        }
    }
    bd[globalRow*N+globalCol]=sum/counter;
}
全局无效矩阵平均值(浮点*ad,浮点*bd,整数半径,整数N)
{
int计数器=0,i,j;
浮动总和=0.0;
int globalRow=blockIdx.y*blockDim.y+threadIdx.y;
int globalCol=blockIdx.x*blockDim.x+threadIdx.x;

对于(i=-radius;问题是我必须为这9种类型的元素(4个角+4个侧边元素+内部元素)编写条件。对于可变半径选项,将所有元素置于一个条件下的有效方法是什么?是零填充(根据半径大小填充额外的行和列)是一种有效的方法吗?不使用共享内存的原因是什么?@Michalosala:首先,我想检查一下在我上面的代码中实现它的有效方法!这肯定是一个令人尴尬的并行问题的例子,共享内存肯定非常有用。但我想先看看基本实现,然后en表示共享内存。旁白:我认为你试图实现的一般术语是卷积。你所说的平均值似乎是高斯核的卷积(这里的“核”不是指CUDA核),不要忘记你的滤波器是可分离的(也就是说,你可以使用2个1D过滤器来代替2D过滤器)。这将加快你的实现速度。边界元素的平均计算并不像我想的那么难。现在我可以使用优化的共享内存实现同样的效果。而且,我在C代码(有问题的部分)中所做的事情绝对是一团糟的-|
__global__ void matrix_avg(float *ad,float *bd, int radius, int N)
{
    int counter =0,i,j;
    float sum=0.0;

    int globalRow = blockIdx.y * blockDim.y + threadIdx.y;
    int globalCol = blockIdx.x * blockDim.x + threadIdx.x;

    for(i=-radius;i<=radius;i++)
    {
        for(j=-radius;j<=radius;j++)
        {
            if(((globalRow+i)<0) || ((globalCol+j)<0) || ((globalRow+i)>=N) || ((globalCol+j)>=N))
            {
                sum = sum + 0;
            }
            else
            {
                sum = sum + ad[(globalRow+i)*N+(globalCol+j)];
                counter++;
            }
        }
    }
    bd[globalRow*N+globalCol]=sum/counter;
}