猿问

如何加速 C# 中的嵌套循环

这是我的一段代码,计算差异。它工作正常但需要很多时间(因为高度和宽度)。

  • “数据”是一个灰度图像位图。

  • “过滤器”是 [3,3] 矩阵。

  • “fh”和“fw”最大值为 3。

我希望加快这段代码的速度。

我也尝试使用并行,但是它不能正常工作(错误超出范围)。

private float[,] Differentiate(int[,] Data, int[,] Filter)

{

    int i, j, k, l, Fh, Fw;


    Fw = Filter.GetLength(0);

    Fh = Filter.GetLength(1);


    float sum = 0;

    float[,] Output = new float[Width, Height];


    for (i = Fw / 2; i <= (Width - Fw / 2) - 1; i++)

    {

        for (j = Fh / 2; j <= (Height  - Fh / 2) - 1; j++)

        {

            sum=0;


            for(k = -Fw/2; k <= Fw/2; k++)

            {

                for(l = -Fh/2; l <= Fh/2; l++)

                {

                    sum = sum + Data[i+k, j+l] * Filter[Fw/2+k, Fh/2+l];

                }

            }


            Output[i,j] = sum;

        }


    }


    return Output;

}


慕斯王
浏览 220回答 2
2回答

烙印99

对于并行执行,您需要在方法的开头删除像变量声明这样的 c 语言,并在实际使用的范围内声明它们,这样它们就不会在线程之间共享。使其并行应该为性能提供一些好处,但是将它们全部设为ParallerFors 并不是一个好主意,因为实际上可以并行运行的线程数量是有限制的。我会尝试仅使用顶级循环来实现它:private static float[,] Differentiate(int[,] Data, int[,] Filter){&nbsp; &nbsp; var Fw = Filter.GetLength(0);&nbsp; &nbsp; var Fh = Filter.GetLength(1);&nbsp; &nbsp; float[,] Output = new float[Width, Height];&nbsp; &nbsp; Parallel.For(Fw / 2, Width - Fw / 2 - 1, (i, state) =>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; for (var j = Fh / 2; j <= (Height - Fh / 2) - 1; j++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var sum = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var k = -Fw / 2; k <= Fw / 2; k++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var l = -Fh / 2; l <= Fh / 2; l++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum = sum + Data[i + k, j + l] * Filter[Fw / 2 + k, Fh / 2 + l];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Output[i, j] = sum;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });&nbsp; &nbsp; return Output;}

四季花海

这是使用 GPU 优于使用 CPU 的任务的完美示例。GPU 每秒能够执行数万亿次浮点运算 (TFlops),而 CPU 性能仍以 GFlops 衡量。要注意的是,只有使用 SIMD 指令(单指令多数据)才有用。GPU 擅长数据并行任务。如果不同的数据需要不同的指令,使用 GPU 没有优势。在您的程序中,位图的元素经过相同的计算:相同的计算只是数据略有不同(SIMD!)。所以使用 GPU 是一个不错的选择。这不会太复杂,因为 GPU 上的计算线程不需要交换信息,它们也不依赖于先前迭代的结果(每个元素将由 GPU 上的不同线程处理)。例如,您可以使用 OpenCL 轻松访问 GPU。
随时随地看视频慕课网APP
我要回答