2012-04-04 31 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

我会在这里使用任务并行数据流库。其设计目的是允许创建可通过显式控制并行度和阻塞语义来链接在一起的进程块。