高度并行的F#程序显示CPU利用率较低

bri*_*rns 11 .net parallel-processing f# multithreading memory-management

纯函数式编程的一个承诺是它很好地并行化.我正在使用具有平庸结果的F#应用程序测试此声明.我的程序通过Array.Parallel并行运行大量的MiniMax搜索.MiniMax算法是纯粹的功能代码 - 没有共享状态,没有锁定,但是高度递归,在搜索树时会创建和销毁大量值.根本没有I/O--一切都在内存中.每个MiniMax搜索需要5-60秒,我在一个带有8个CPU内核的快速盒子上并行运行大约100个.遗憾的是,CPU利用率达到65%左右,通常在45-60%的范围内.

我使用Visual Studio Concurrency Visualizer分析了我的应用程序,发现它在大约40%的时间内被阻止.所有阻塞调用似乎都在.NET垃圾收集器或其他.NET内存管理例程中.有没有办法优化这种行为,而无需用C++等低级语言重写整个程序?很明显,问题在于我正在创建和销毁太多的对象,但这在惯用的F#代码中很难避免.也许我错过了同步问题的其他一些原因?

谢谢.

更新:我做了两个更改:禁用超线程并在我的配置文件中使用gcServer.这使我的测试用例的执行时间从32秒减少到13秒!CPU利用率也高得多.感谢所有提出建议的人.

小智 9

您应该将应用程序配置为使用服务器垃圾回收.有关详细信息,请参阅gcServer元素的文档 .默认的工作站垃圾收集器不允许分配繁重的程序扩展到多个核心.