0

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

__global__ void matrix_avg(float *ad,float *bd)
{
    float t1, t2, t3, t4, t5, t6, t7, t8, t9, avg;
    int i = blockIdx.y * blockDim.y + threadIdx.y;
    int j = blockIdx.x * blockDim.x + threadIdx.x;
    int k = (i*N)+(j);

    if(i==0)
        {
            if(j==0)
            {
                bd[k]=(ad[k+1]+ad[k+N]+ad[k+N+1]+ad[k])/4;
            }
            else if(j==N-1)
            {
                bd[k]=(ad[k-1]+ad[k+N]+ad[k+N-1]+ad[k])/4;
            }
            else
            {
                bd[k]=(ad[k-1]+ad[k+1]+ad[k+N-1]+ad[k+N]+ad[k+N+1]+ad[k])/6;
            }
        }
        else if(i==N-1)
        {
            if(j==0)
            {
                bd[k]=(ad[k+1]+ad[k-N]+ad[k-N+1]+ad[k])/4;
            }
            else if(j==N-1)
            {
                bd[k]=(ad[k-1]+ad[k-N]+ad[k-N-1]+ad[k])/4;
            }
            else
            {
                bd[k]=(ad[k-1]+ad[k+1]+ad[k-N-1]+ad[k-N]+ad[k-N+1]+ad[k])/6;
            }
        }
        else if(j==0)
        {
            bd[k]=(ad[k-N]+ad[k-N+1]+ad[k+1]+ad[k+N]+ad[k+N+1]+ad[k])/6;
        }
        else if(j==N-1)
        {
            bd[k]=(ad[k-N-1]+ad[k-N]+ad[k-1]+ad[k+N-1]+ad[k+N]+ad[k])/6;
        }
        else
        {
            t1=ad[k-N-1];
            t2=ad[k-N];
            t3=ad[k-N+1];
            t4=ad[k-1];
            t5=ad[k+1];
            t6=ad[k+N-1];
            t7=ad[k+N];
            t8=ad[k+N+1];
            t9=ad[k];
            avg=(t1+t2+t3+t4+t5+t6+t7+t8+t9)/9;
            bd[k]=avg;
        }
}

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

4

1 回答 1

1

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

__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 - 矩阵维度。(我暂时将其保留为方阵)

radius - 执行平均计算范围的半径

于 2014-08-26T14:30:00.603 回答