gpt4 book ai didi

c# - 从 list> 中累积值的并行版本代码

转载 作者:行者123 更新时间:2023-11-30 22:14:58 26 4
gpt4 key购买 nike

我再次努力理解并行计算的一些东西。在我正在处理的代码中,我有一个扩展 list<list<double>> 的类.在这个类中,我正在编写一个方法来返回 list<list<double>> 中值的平均值。 .此方法是私有(private)的。

public class myClass : list<list<double>>
{
//properties and stuff
private double average()
{
//method body
}
}

我为这个方法做了两个版本,它们都有效。第一个版本是连续的:

private double average()
{
double avg = 0;
for (int i = 0; i < this.Count; i++)
{
for (int j = 0; j < this[0].Count; j++)
{
avg += this[i][j];
}
}
avg = avg / (this.Count*this[0].Count);
return avg;
}

并行的是第二个版本:

private double average()
{
double avg = 0;
double[] cumsum = new double[this.Count];
Parallel.For(0, this.Count, i =>
{
cumsum[i] = 0;
for (int j = 0; j < this[0].Count; j++)
{
cumsum[i] += this[i][j];
}
});
avg = cumsum.Sum() / ((this.Count * this[0].Count));
return avg;
}

作为学习练习,我尝试使用更复杂的并行线程来搞砸事情。我的想法是在没有对行求和的中间数组的情况下凑合。具体来说,这是我的尝试(不起作用):

private double average()
{
double avg = 0;
Parallel.For<double>(0, this.Count, () => 0, (i, loop, sub) =>
{
for (int j = 0; j < this[0].Count; j++)
{
sub += this[i][j];
}
return sub;
},
(x) =>
{
double tot = avg;
Interlocked.CompareExchange(ref avg, tot+sub, tot);
});
return avg / ((this.Count * this[0].Count));
}

这个片段有(至少)两个错误。它给我的第一个错误是 sub += this[i][j]; :

The best overloaded method match for 'System.Collections.Generic.List>.this[int]' has some invalid arguments

这里我不理解这个错误,因为i和j都是int类型。

然后我在 Interlocked.CompareExchange(ref avg, tot+sub, tot); 上有一个进一步的错误(意料之中,因为我不太明白这个方法是如何工作的):

The name 'sub' does not exist in the current context

有人可以指出最后一段的正确形式吗?和/或一些 Material 来澄清这些事情?我读自 http://msdn.microsoft.com/en-us/library/dd460703.aspx但这并没有帮助我弄清楚事情。

最佳答案

就我个人而言,我会使用:

double sum = yourListOfList.AsParallel().SelectMany(list => list).Average();

为了修复您的方法,您需要在本地最终 lambda 中使用您的循环状态。 (您目前根本没有使用 x。)

double sum = 0;
var syncObj = new object();
Parallel.For<double>(0, this.Count, () => 0, (i, loop, sub) =>
{
var innerList = this[i];
for (int j = 0; j < innerList.Count; j++)
{
sub += innerList[j];
}
return sub;
},
(x) =>
{
lock(syncObj)
sum += x;
});
return sum / ((this.Count * this[0].Count));

请注意,您的版本(和我的“更正”)有很多缺点。假设每个子列表的长度与 this[0] 相同,类型不保证或建议。

关于c# - 从 list<list<double>> 中累积值的并行版本代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18216438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com