我試圖讓我的代碼的一部分並行運行,我試圖在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