我目前正在编写一个批量处理算法,用于从磁盘流式传输音频中的音高检测。我已经收紧了我的算法,以便它几乎实时地运行串行流数据。
理想情况下,我希望系统的工作速度比实时快,这样我就可以将实时数据交给它,并且在没有很大延迟后生成音高轨迹数据。
现在让我印象深刻的是数据的串行处理是我可以提供大量加速的地方。我在四核 i7(有 8 个硬件线程)上运行,所以我应该能够通过跨多个块扩展处理来显着提高速度。
目前,我正在执行以下操作:
- 从磁盘流式传输数据
- 缓冲数据,直到我有我想要分析的窗口大小。
- 处理数据窗口。
- 将数据复制回 n 个样本(其中 n 是我想要滑动的量(在 80 毫秒的窗口中,这可以低至 1 毫秒!)
- 冲洗并重复。
现在让我感到震惊的是,一旦我有了一个窗口,我就可以轻松地将该数据复制到给定的线程工作缓冲区中(以及提供将结果写入的内存位置)。通过这种方式,我可以有效地缓冲多达 7 个(让线程 8 保持打开以泵送数据)线程池将处理的数据线程。
当我尝试提交第 8 个音频窗口时,我希望池阻塞,直到有线程可用于处理数据等等。我的想法是让 7 个线程不断地处理数据。根据以前的经验,我希望这样做可以提高 5 倍的速度。
过去我在 C++ 下编写了我自己的基于任务的系统,该系统可以完美地完成这项工作,但这个应用程序是在 C# 下开发的。为了在 C++ 下以低开销获得良好的并行性,我花费了大量时间来构建良好的无锁队列机制。
我宁愿希望,在 C# 下,有人会为我减轻痛苦。但是我找不到任何似乎可行的东西。我查看了 System.Threading.ThreadPool ,它似乎无法检查当前有多少线程在运行。更不用说开销似乎令人望而却步。然后出现了一个大问题,即我无法重新使用现有的预分配结构(这在我的处理中很重要),这迫使我每次提交工作项时都重新创建它。这有一个巨大的缺点,那就是我生成工作的速度比我处理它的速度要快,所以我最终不仅浪费了大量的时间来设置我真的不需要的结构和工作空间,而且我的内存使用也失控了。
然后我发现了 System.Threading.Tasks 但这似乎也没有提供我所追求的功能。
我想我可以通过互操作使用我的 C++ 任务管理器,但我真的认为在这个时代已经有人设置了类似的东西。所以我错过了什么吗?或者任何人都可以向我提供这样一个任务管理引擎的链接吗?