2012-04-04 74 views
3

我目前正在爲從磁盤流式傳輸的音頻中的音高檢測編寫批量處理算法。我已經收緊了我的算法,以便它幾乎實時地運行串行流數據。用於.NET的任務池系統

理想情況下,我希望系統工作的方式比實時更快,這樣我就可以把它傳給實時數據,並且在產生音調軌道數據之後不會產生巨大的延遲。

現在令我感到震驚的是數據的串行處理是我可以提供很多加速的地獄。我在一個四核i7上運行(有8個硬件線程),所以我應該能夠通過跨多個塊的處理來顯着提高速度。

當它進入我現在做到以下幾點:

  1. 關閉磁盤流數據
  2. 緩衝數據,直到我有我要分析的窗口大小。
  3. 處理數據窗口。
  4. 將數據複製回正樣本(其中n是我想滑動量(這可以低至1ms的靠背在80ms的窗口!)
  5. 沖洗和重複。

現在讓我感到有一次我有了一個窗口,我可以很容易地將這些數據複製到一個給定的線程工作緩衝區(以及提供一個內存位置結果將被寫入),這樣我可以有效地緩衝多達7個線程打開以抽取數據)線程池將會處理的數據線程

當我嘗試提交音頻的第8個窗口時,我希望池阻塞unti l線程可用於處理數據等。我的想法是保持7個線程不斷地處理數據。從以往的經驗來看,我預計這樣做的速度會提高5倍。

在過去,我已經在C++下編寫了自己的基於任務的系統,完美地完成這項工作,但是這個應用程序正在C#下開發。爲了在C++下以低開銷獲得良好的並行性,我花費了大量的時間來構建一個良好的無鎖定排隊機制。

我很希望在C#下有人會爲我這樣做而痛苦。但是我找不到任何似乎可行的東西。我看了一下System.Threading.ThreadPool,它似乎沒有辦法檢查當前有多少線程正在運行。更不用說管理費用似乎令人望而卻步了。然後出現的一個大問題是,我無法重新使用現有的預分配結構(這在我的處理過程中很重要),這迫使我在每次提交工作項時重新創建它。這有一個巨大的缺點,那就是我的工作速度超過了我的處理速度,所以不僅會浪費大量的時間來設置我真正不需要的結構和工作空間,而且會使我的內存使用情況失去控制。

然後我發現了System.Threading.Tasks,但是這似乎並沒有提供我所追求的功能。

我想我可以通過互操作使用我的C++任務管理器,但我真的認爲在這個時代有人已經設置了類似的東西。所以我錯過了什麼?或者任何人都可以提供給我一個這樣的任務管理引擎的鏈接?

+0

我不確定我關注。爲什麼在創建「工作項目」時需要複製結構?爲什麼不只是傳遞一個引用(就是 - 把它放在一個類中並傳遞實例)? – zmbq 2012-04-04 20:12:30

+4

我沒有看到任何東西比簡單的單生產者/多消費者算法更需要。 – 2012-04-04 20:14:07

+0

@zmbq:問題是我需要一組LARGE便箋區來完成我的處理。這些便箋簿必須預先設置好,因爲它們並不是很容易設置的。我用C++系統完成的事情是預先設置8個這樣的結構,然後將它們重新用於當前準備好處理的任何數據。另一個問題是這些便箋本非常大,所以我不能隨意創建其中的50個(例如50個需要大約0.5GB的內存)。 – Goz 2012-04-04 20:21:17

回答

4

Task Parallel Library專爲您正在嘗試解決的任務而設計和實施!你也可以管理這個過程。

所以,你必須確保:

+0

我更希望TPL能夠做我想做的事情......但到目前爲止,我還沒有太多的運氣計算出來......例如,我如何要求一個項目排隊,但阻止排隊,直到線程可用? – Goz 2012-04-04 20:23:02

+1

@Goz - 在BlockingCollecition鏈接下。 – 2012-04-04 20:27:22

+0

@HenkHolterman:你有什麼可以指點我的例子嗎? – Goz 2012-04-04 20:28:28

3

那麼,我一直在這些情況下,我推薦使用ZeroMQ。它可以讓你很容易地控制消費者的數量。

至於你的便箋簿區域,首先,0.5GB在今天和這個時代並不是很多的記憶。我認爲我的手機有更多的RAM,更不用說我的桌面了......如果你想在內存消耗方面變得非常簡單,只需爲每個線程創建一個便箋區,將其全部放入池中並讓製作人獲得在排隊任務之前在臨時區域上,附加任務的該區域。消費者完成後,將便箋式區域返回到池中。

+1

我不知道你的情況,但是當我只需要大約80兆的時候,我只需要一半的演出就好像是一種可怕的記憶浪費......唉,我希望更多的程序員像我這樣想:( – Goz 2012-04-04 20:36:28

+2

這不是浪費內存 - 它會在那裏在你的程序完成之後......真的,除非它是一個真正的問題,否則沒有必要優化你的內存佔用。是真的嗎? – zmbq 2012-04-04 20:40:03

+0

是的......簡單地說..浪費任何不必要的資源都是不好的......但讓我們沒有深入探討爲什麼毫無意義的過度內存使用是一件壞事 – Goz 2012-04-04 20:46:06

1

我會在這裏使用任務並行數據流庫。其設計目的是允許創建可通過顯式控制並行度和阻塞語義來鏈接在一起的進程塊。