我目前正在爲從磁盤流式傳輸的音頻中的音高檢測編寫批量處理算法。我已經收緊了我的算法,以便它幾乎實時地運行串行流數據。用於.NET的任務池系統
理想情況下,我希望系統工作的方式比實時更快,這樣我就可以把它傳給實時數據,並且在產生音調軌道數據之後不會產生巨大的延遲。
現在令我感到震驚的是數據的串行處理是我可以提供很多加速的地獄。我在一個四核i7上運行(有8個硬件線程),所以我應該能夠通過跨多個塊的處理來顯着提高速度。
當它進入我現在做到以下幾點:
- 關閉磁盤流數據
- 緩衝數據,直到我有我要分析的窗口大小。
- 處理數據窗口。
- 將數據複製回正樣本(其中n是我想滑動量(這可以低至1ms的靠背在80ms的窗口!)
- 沖洗和重複。
現在讓我感到有一次我有了一個窗口,我可以很容易地將這些數據複製到一個給定的線程工作緩衝區(以及提供一個內存位置結果將被寫入),這樣我可以有效地緩衝多達7個線程打開以抽取數據)線程池將會處理的數據線程
當我嘗試提交音頻的第8個窗口時,我希望池阻塞unti l線程可用於處理數據等。我的想法是保持7個線程不斷地處理數據。從以往的經驗來看,我預計這樣做的速度會提高5倍。
在過去,我已經在C++下編寫了自己的基於任務的系統,完美地完成這項工作,但是這個應用程序正在C#下開發。爲了在C++下以低開銷獲得良好的並行性,我花費了大量的時間來構建一個良好的無鎖定排隊機制。
我很希望在C#下有人會爲我這樣做而痛苦。但是我找不到任何似乎可行的東西。我看了一下System.Threading.ThreadPool,它似乎沒有辦法檢查當前有多少線程正在運行。更不用說管理費用似乎令人望而卻步了。然後出現的一個大問題是,我無法重新使用現有的預分配結構(這在我的處理過程中很重要),這迫使我在每次提交工作項時重新創建它。這有一個巨大的缺點,那就是我的工作速度超過了我的處理速度,所以不僅會浪費大量的時間來設置我真正不需要的結構和工作空間,而且會使我的內存使用情況失去控制。
然後我發現了System.Threading.Tasks,但是這似乎並沒有提供我所追求的功能。
我想我可以通過互操作使用我的C++任務管理器,但我真的認爲在這個時代有人已經設置了類似的東西。所以我錯過了什麼?或者任何人都可以提供給我一個這樣的任務管理引擎的鏈接?
我不確定我關注。爲什麼在創建「工作項目」時需要複製結構?爲什麼不只是傳遞一個引用(就是 - 把它放在一個類中並傳遞實例)? – zmbq 2012-04-04 20:12:30
我沒有看到任何東西比簡單的單生產者/多消費者算法更需要。 – 2012-04-04 20:14:07
@zmbq:問題是我需要一組LARGE便箋區來完成我的處理。這些便箋簿必須預先設置好,因爲它們並不是很容易設置的。我用C++系統完成的事情是預先設置8個這樣的結構,然後將它們重新用於當前準備好處理的任何數據。另一個問題是這些便箋本非常大,所以我不能隨意創建其中的50個(例如50個需要大約0.5GB的內存)。 – Goz 2012-04-04 20:21:17