我试图让我的代码的一部分并行运行,我试图在C#中使用ThreadPool,以避免任何头痛,但似乎我要求太多的池,我的代码实际上它运行得更慢!C#并行处理选项
下面的代码解释了我想要做的事情,我有大量的音频样本(取决于缓冲区大小从512-> 4096的任何地方),需要插入,传播和读取节点(从n = 4到n = 16)。这必须以样本为基础进行,因此我唯一的优化选择是对网络中存在的每个节点采用插入/传播/读取并具有并行操作的部分。该操作在每个游戏帧中调用一次,并且在游戏的整个生命周期中都需要。看一下剖析器,散射操作需要大量的时间,所以它是一个很好的候选者(我已经完成了传统的优化)。目前,我有一个线程池工作人员为一个工作项目中的所有节点完成工作,只是为了启动和运行,但稍后可以拆分工作。
我认为下面的代码的问题是插入到线程池的工作项的频率,我也读过某些地方,线程需要一段时间才能旋转起来,所以如果线程池创建更多,它不neccserally帮助。有没有人有任何其他并行处理方法的建议,或可以发现我的线程池实施的任何错误?
public void propagateNetwork() {
int numSampsToConsume = Mathf.min(inSamples.Count,buffersize);
for (int i = 0; i < numSampsToConsume; i++) {
outVal = 0.0f;
inVal = inSamples.Dequeue() * networkInScale;
directDelay.write (inVal);
directVal = directDelay.read();
directVal *= directAtt;
for (j = 0; j < network.Count; j++) {
outVal += network [j].getOutgoing();
network [j].inputIncoming (inVal);
}
ThreadPool.QueueUserWorkItem (scatteringThreadPoolWrapper);
scatteringThreadDone.WaitOne();
outVal += directVal;
outSamples.Enqueue (outVal);
}
}
public void scatteringThreadPoolWrapper(object threadConext) {
doScatteringForNodeRange (0, network.Count);
}
public void doScatteringForNodeRange(int min,int max) {
for (int i = min; i < max; i++) {
network[i].doScattering (doLateReflections);
}
scatteringThreadDone.Set();
}
如果你排队然后马上等待,那不就是删除了吗?你不应该排队所有的工作项目,然后等待他们在另一个循环完成?也许考虑用'Parallel.for'替代你的外部? – NetMage
也许我误解了线程池的功能,但我认为我分配给它的每个任务可能都在不同的线程上。因此总体来说它会更快完成?我知道在示例代码中,我还没有将工作分解,这只是一个测试,看它是否可行。我需要等待,因为每个样本必须在完成传播之前完成传播,出于同样的原因,并行是不可能的。 – Rampartisan
每个任务可能位于不同的线程上,但是如果您将任务发送到另一个线程,然后等待在主线程上运行另一个任务之前取回答案,那么当然您会更慢。您仍然一次只运行一个线程,但是您添加了创建线程和跨线程通信的开销。 – NetMage