For方法来从Array计算数据

For方法来从Array计算数据

想要:求和x和求和x * x。其中x = line [i]。
因为有多个线程想要读/写“ sumAll”和“ sumAllQ”,所以我需要锁定其访问权限。
问题在于,这种锁定会在这里序列化事物。我将需要在#“ Environment.ProcessorCount”中拆分此操作以进行循环,每个循环求和数组的一部分,最后求和结果。但是,我该如何以编程方式制作它?

样例代码:

//line is a float[]
Parallel.For(0, line.Length,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
i =>
{
    x = (double)line[i];
    lock (sumLocker)
    {
        sumAll += x;
        sumAllQ += x * x;
    }
});


编辑1:
Matthew Watson回答基准结果

在家。 CPU核心2 Quad Q9550 @ 2.83 GHz:

Result via Linq:      SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via loop:      SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via partition: SumAll=49999950000, SumAllQ=3,333328333335E+15
Via Linq took: 00:00:02.6983044
Via Loop took: 00:00:00.4811901
Via Partition took: 00:00:00.1595113


工作中。 CPU i7 930 2.8 GHz:

Result via Linq:      SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via loop:      SumAll=49999950000, SumAllQ=3,33332833333439E+15
Result via partition: SumAll=49999950000, SumAllQ=3,333328333335E+15
Via Linq took: 00:00:01.5728736
Via Loop took: 00:00:00.3436929
Via Partition took: 00:00:00.0934209

最佳答案

如注释中所建议,您可以在LINQ中使用AggregateAsParallel完成此操作。例如:

using System.Linq;

//A class to hold the results.
//This can be improved by making it immutable and using a constructor.
public class Result
{
    public double SumAll { get; set; }
    public double SumAllQ { get; set; }
}


您可以像这样使用LINQ:

var result = line.AsParallel().Aggregate(new Result(), (input, value) => new Result {SumAll = input.SumAll+value, SumAllQ = input.SumAllQ+value*value});


甚至更好:

var pline = line.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount);
var result = new Result { SumAll = pline.Sum(), SumAllQ = pline.Sum(x => x * x) };


AsParallel不能直接指定选项,但是您可以使用.WithDegreeOfParallelism().WithExecutionMode().WithMergeOptions()来提供更多控制权。您甚至可能必须使用WithDegreeOfParallelism使其与多个线程一起运行。

关于c# - 正确的Parallel.For方法来从Array计算数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16821403/

10-10 15:34