我目前正在为从磁盘流式传输的音频中的音高检测编写批量处理算法。我已经收紧了我的算法,以便它几乎实时地运行串行流数据。用于.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