Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous F#异步maxDegreeOfParallelism的最佳使用_Asynchronous_F# - Fatal编程技术网

Asynchronous F#异步maxDegreeOfParallelism的最佳使用

Asynchronous F#异步maxDegreeOfParallelism的最佳使用,asynchronous,f#,Asynchronous,F#,我使用F#异步工作流已经有一段时间了,我非常喜欢它。最近,我在做一个项目,涉及在单独的Deedle框架上进行许多独立的计算,我使用了Async.Parallel。在这些异步中,许多其他异步也是以并行方式计算的(嵌套异步?)。我的代码是这样的 让processRoomAsync房间= 异步的{ 让我们在房间里做点什么 返回x } 让processCompressorAsync压缩器= 异步的{ let rooms=从压缩机获取房间 让!y= Array.map processRoomAsync文件

我使用F#异步工作流已经有一段时间了,我非常喜欢它。最近,我在做一个项目,涉及在单独的Deedle框架上进行许多独立的计算,我使用了
Async.Parallel
。在这些异步中,许多其他异步也是以并行方式计算的(嵌套异步?)。我的代码是这样的

让processRoomAsync房间=
异步的{
让我们在房间里做点什么
返回x
}
让processCompressorAsync压缩器=
异步的{
let rooms=从压缩机获取房间
让!y=
Array.map processRoomAsync文件室
|>异步并行
返回与您一起做某事
}
让我们来看看建筑=
let compressors=为建筑获取压缩机
让processResult=
Array.map processCompressorAsync压缩器
|>异步并行
|>异步运行
用结果处理结果做某事
上述规范的理念是我有一座
建筑
,例如一家酒店,有许多空调
压缩机
,每个
压缩机
为许多
房间
提供服务。我需要处理连接到一台
压缩机的所有
房间
数据,以便对
压缩机
电源进行建模。然后对所有
压缩器
数据进行聚合,以给出
构建
的总体结果

当异步数较少时,与单个异步执行时间相比,结果是预期的

然而,当异步的数量超过100时,我注意到计算时间显著降低。 我读了一些关于
maxdegreeofpparallelism
的文档,但我不太明白应该使用哪个数字。应该是我计算机中vCPU的数量吗?如果是这样,那些嵌套的
Async.Parallel
?我尝试了几种价值观,但改进幅度很小

我在某个地方读到,我应该使用
MailboxProcessor
,但我不太明白这一点。另外,一些文档说,
async
用于I/O绑定,而不是用于计算,这似乎建议使用
Hopac
,但我想知道是否值得花时间研究它

感谢并抱歉提出这么长的问题。

潜在问题:

  • 您运行的线程数超出了计算机的能力 处理,所以它暂停一个线程以返回到另一个线程,等等 在…上这就是maxDegreeOfParallelism可以帮助设置潜在问题的地方:

    • 您运行的线程数超出了计算机的能力 处理,所以它暂停一个线程以返回到另一个线程,等等
      在…上这就是maxDegreeOfParallelism可以帮助将其设置为的地方。感谢您的评论,我的工作流程包括从csv读取数据并将结果写入csv,但是检查磁盘任务管理器,我发现速度没有接近限制(这是一个NVME SSD)。我需要使用
      Async.Parallel
      ,因为一些
      建筑
      有许多
      压缩器
      和很少的
      房间
      ,而另一些
      建筑
      有很少的
      压缩器
      和许多
      房间
      ,因此我想最大限度地提高CPU利用率。@JoseVu。你不能将列表平铺成元组(压缩程序、房间)吗?这样,您就可以运行单个异步。Parallel@JoseVu您能详细说明一下,您的函数是纯函数还是IO?在工作流开始时(代码之前),所有csv文件都加载到许多
      Deedle.Frame
      room
      只是一个
      Deedle.Frame
      。函数
      do\u something
      只是用于预处理数据的计算,而
      do\u something\u with_y
      用于建模并将结果保存到csv文件中。我不确定是否可以将数据展平到
      (压缩机、房间)
      。我的想法是,我有一个
      大楼
      ,里面有许多空调
      压缩机
      ,每个
      压缩机
      为许多
      房间
      提供服务。我需要处理所有连接到一个
      压缩器的
      房间
      ,以便为
      压缩器
      电源建模。感谢您的评论,我的工作流程包括从csv读取数据并将结果写入csv,但检查磁盘任务管理器,我发现速度没有接近限制(这是一个NVME SSD)。我需要使用
      Async.Parallel
      ,因为一些
      建筑
      有许多
      压缩器
      和很少的
      房间
      ,而另一些
      建筑
      有很少的
      压缩器
      和许多
      房间
      ,因此我想最大限度地提高CPU利用率。@JoseVu。你不能将列表平铺成元组(压缩程序、房间)吗?这样,您就可以运行单个异步。Parallel@JoseVu您能详细说明一下,您的函数是纯函数还是IO?在工作流开始时(代码之前),所有csv文件都加载到许多
      Deedle.Frame
      room
      只是一个
      Deedle.Frame
      。函数
      do\u something
      只是用于预处理数据的计算,而
      do\u something\u with_y
      用于建模并将结果保存到csv文件中。我不确定是否可以将数据展平到
      (压缩机、房间)
      。我的想法是,我有一个
      大楼
      ,里面有许多空调
      压缩机
      ,每个
      压缩机
      为许多
      房间
      提供服务。我需要处理所有连接到一个
      压缩机的
      房间
      ,以便对
      压缩机
      电源进行建模。
        let yProcessor = MailboxProcessor.Start(fun inbox ->
              let rec messageLoop acc = async{
      
                  let! msg = inbox.Receive()
      
                  let result = do_something_with_y msg
      
                  return! messageLoop acc::result
                  }
      
              messageLoop ([])
              )
      
      
      let processCompressorAsync compressor = 
         get_rooms_from_compressor compressor
         |>  Array.map do_something
      
      let processBuilding building = 
          let compressors = get_compressors_for_building building
          let preComputation = 
              compressors
              |> Array.map processCompressorAsync
              |> Async.Parallel
              |> Async.RunSynchronously
      
          let processResult = 
              preComputation
              |> Array.iter (yProcessor.Post)
              |> Async.Parallel
              |> Async.RunSynchronously