此刻我的代码如下:
public float[] Next(int samples)
{
float[] result = new float[samples];
for (int i = 0; i < samples; ++i)
result[i] = 0;
foreach (var b in boards)
{
for (int i = 0; i < samples; ++i)
result[i] += b.Next();
}
return result;
}
此功能每秒调用44100次,几乎占用了所有处理能力。 board.Next()
函数彼此完全独立运行,因此我认为应该有一种多线程的方法。
我尝试了以下操作:
public float[] Next(int samples)
{
float[] result = new float[samples];
for (int i = 0; i < samples; ++i)
result[i] = 0;
Parallel.ForEach(boards, b =>
{
for (int i = 0; i < samples; ++i)
result[i] += b.Next();
});
return result;
}
但这只会使情况变得更糟。
是否有一种方法可以对该进程进行多线程处理而又不会产生大量线程开销?
通常少于10个板。永远不要超过100。
board.Next()
方法与调用方法不同。也就是说,定义此Next()
的类与board
是不同的类。
已解决:
有点,我想...
我替换了这个:
Parallel.ForEach(boards, b =>
{
for (int i = 0; i < samples; ++i)
result[i] += b.Next();
});
与此:
Parallel.ForEach(boards, b =>
{
for (int i = 0; i < samples; ++i)
{
var next = b.Next();
lock (result)
result[i] += next;
}
});
显然,C#在将结果添加到后会自动锁定。这是我所期望的。我没想到的是,在评估右侧之前这样做了。因此,通过将加法和对Next()的调用拆分为单独的语句,可以并行调用Next()。
答案 0 :(得分:0)
严重的是,你犯了更大的错误。
44100对于循环而言不是特别高的数字。但是你有初学者的错误:
float []结果=新的float [samples];
这是44100个分配,可能需要或不需要。如果函数是控制函数传入一个数组并说出它想要多少个样本(可选地,取决于数组的长度),而您不返回数组而是返回实际交付的样本数(因为可能存在该数目),则此类型的标准少一点。)
在并行进行foreach考虑b.next之前,我先对其进行测量并将测量数字放在此处-因为在大多数情况下,这没有意义。
这样您就可以避免分配-相信我,您不希望每秒分配44100个阵列。那接近自杀。