[英]How to speed up nested loops in C#
这是我的一段代码,用于计算差异。 它可以正常工作,但是会花费很多(因为高度和宽度)。
我希望加快此代码的速度。
我也尝试使用并行,因为它不能正常工作(超出范围的错误)。
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;
}
对于并行执行,您需要在方法的开头删除c语言(如变量声明),并在使用它们的实际范围内声明它们,以便它们不会在线程之间共享。 使其并行应该可以为性能带来一些好处,但是使它们全部为ParallerFors并不是一个好主意,因为实际上可以并行运行的线程数量是有限的。 我会尝试只使用顶级循环:
private static float[,] Differentiate(int[,] Data, int[,] Filter)
{
var Fw = Filter.GetLength(0);
var Fh = Filter.GetLength(1);
float[,] Output = new float[Width, Height];
Parallel.For(Fw / 2, Width - Fw / 2 - 1, (i, state) =>
{
for (var j = Fh / 2; j <= (Height - Fh / 2) - 1; j++)
{
var sum = 0;
for (var k = -Fw / 2; k <= Fw / 2; k++)
{
for (var 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;
}
这是使用GPU比使用CPU更好的任务的完美示例。 GPU每秒可以执行数万亿个浮点运算(TFlops),而CPU性能仍以GFlops为单位。 要注意的是,如果您使用SIMD指令(单指令多数据),那就太有用了。 GPU在数据并行任务方面表现出色。 如果不同的数据需要不同的指令,则使用GPU没有优势。
在您的程序中,位图的元素经过相同的计算:只是在数据略有不同的情况下进行相同的计算(SIMD!)。 因此,使用GPU是一个不错的选择。 这不会太复杂,因为使用您的计算,GPU上的线程将不需要交换信息,也不必依赖于先前迭代的结果(每个元素将由GPU上的不同线程处理)。
例如,您可以使用OpenCL轻松访问GPU。 有关OpenCL和使用GPU的更多信息,请访问: https : //www.codeproject.com/Articles/502829/GPGPU-image-processing-basics-using-OpenCL-NET
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.