3

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

理想情况下,我希望系统的工作速度比实时快,这样我就可以将实时数据交给它,并且在没有很大延迟后生成音高轨迹数据。

现在让我印象深刻的是数据的串行处理是我可以提供大量加速的地方。我在四核 i7(有 8 个硬件线程)上运行,所以我应该能够通过跨多个块扩展处理来显着提高速度。

目前,我正在执行以下操作:

  1. 从磁盘流式传输数据
  2. 缓冲数据,直到我有我想要分析的窗口大小。
  3. 处理数据窗口。
  4. 将数据复制回 n 个样本(其中 n 是我想要滑动的量(在 80 毫秒的窗口中,这可以低至 1 毫秒!)
  5. 冲洗并重复。

现在让我感到震惊的是,一旦我有了一个窗口,我就可以轻松地将该数据复制到给定的线程工作缓冲区中(以及提供将结果写入的内存位置)。通过这种方式,我可以有效地缓冲多达 7 个(让线程 8 保持打开以泵送数据)线程池将处理的数据线程。

当我尝试提交第 8 个音频窗口时,我希望池阻塞,直到有线程可用于处理数据等等。我的想法是让 7 个线程不断地处理数据。根据以前的经验,我希望这样做可以提高 5 倍的速度。

过去我在 C++ 下编写了我自己的基于任务的系统,该系统可以完美地完成这项工作,但这个应用程序是在 C# 下开发的。为了在 C++ 下以低开销获得良好的并行性,我花费了大量时间来构建良好的无锁队列机制。

我宁愿希望,在 C# 下,有人会为我减轻痛苦。但是我找不到任何似乎可行的东西。我查看了 System.Threading.ThreadPool ,它似乎无法检查当前有多少线程在运行。更不用说开销似乎令人望而却步。然后出现了一个大问题,即我无法重新使用现有的预分配结构(这在我的处理中很重要),这迫使我每次提交工作项时都重新创建它。这有一个巨大的缺点,那就是我生成工作的速度比我处理它的速度要快,所以我最终不仅浪费了大量的时间来设置我真的不需要的结构和工作空间,而且我的内存使用也失控了。

然后我发现了 System.Threading.Tasks 但这似乎也没有提供我所追求的功能。

我想我可以通过互操作使用我的 C++ 任务管理器,但我真的认为在这个时代已经有人设置了类似的东西。所以我错过了什么吗?或者任何人都可以向我提供这样一个任务管理引擎的链接吗?

4

3 回答 3

4

任务并行库专为您要解决的任务而设计和实现!您也可以通过管道处理此过程。

所以你必须确保:

于 2012-04-04T20:13:22.420 回答
3

好吧,在这些情况下,我建议使用ZeroMQ。它可以让你很容易地控制消费者的数量。

至于您的便签本区域,首先,0.5GB 在当今时代并不是很多内存。我认为我的手机有更多的内存,更不用说我的桌面了......如果你想真正轻松地减少内存消耗,只需为每个线程创建一个暂存区,将它们全部放在一个池中并让生产者获得在排队任务之前的便签本区域,附加任务的该区域。当消费者完成后,将便签本区域返回到池中。

于 2012-04-04T20:33:00.880 回答
1

我会在这里使用 Task Parallel 数据流库。它旨在允许创建可以链接在一起的进程块,并显式控制并行度和阻塞语义。

于 2012-11-29T12:42:20.500 回答