gpt4 book ai didi

asynchronous - 如何让所有核心参与异步并行化?

转载 作者:行者123 更新时间:2023-12-03 03:48:16 25 4
gpt4 key购买 nike

以下函数通过首先将列表分解为大块然后处理每个 block 来并行处理列表。

let chunkList chunkSize (xs : list<'T>) = 
query {
for idx in 0..(xs.Length - 1) do
groupBy (idx / chunkSize) into g
select (g |> Seq.map (fun idx -> xs.[idx]))
}
let par (foo: 'T -> 'S) (xs: list<'T>) =
xs
|> List.map (fun x -> async { return foo x })
|> Async.Parallel
|> Async.RunSynchronously
|> Array.toList

let parChunks chunkSize (f: 'T -> 'S) (xs: list<'T>) =
chunkList chunkSize xs |> Seq.map List.ofSeq |> List.ofSeq
|> par (List.map f)
|> List.concat

此函数用于测试 parChunks:

let g i = [1..1000000] |> List.map (fun x -> sqrt (float (1000 * x + 1))) |> List.head

运行标准的 List.Seq 和 block 大小等于列表大小 1/2 的 `parChunk`` 会带来性能提升:

List.map g [1..100];; // Real: 00:00:28.979, CPU: 00:00:29.562

parChunks 50 g [1..100];; // Real: 00:00:23.027, CPU: 00:00:24.687

但是,当 block 大小等于列表大小的 1/4 时,性能几乎相同。我没想到会出现这种情况,因为我的处理器 (Intel 6700HQ) 有四个核心。

parChunks 25 g [1..100];; // Real: 00:00:21.695, CPU: 00:00:24.437

查看任务管理器中的性能应用程序会发现四个核心从未被使用过。

有没有办法让所有四个核心都参与这个计算?

最佳答案

我认为你把这个问题过于复杂化了。

异步工作流程的主要用途不是用于 CPU 密集型工作,而是用于 IO 密集型工作,以避免在等待会出现一定延迟的结果时阻塞线程。

尽管您可以使用 async 并行处理 CPU 密集型工作,但这样做并不是最理想的。

通过在 Array 而不是 List 上使用 Array.Parallel 模块,可以更轻松地实现您想要的效果。

let g i = 
[|1..1000000|]
|> Array.Parallel.map (fun x -> sqrt (float (1000 * x + 1)))
|> Array.head

无需编写您自己的分块和合并代码,这一切都会为您处理,并且根据我的测量,它要快得多。

关于asynchronous - 如何让所有核心参与异步并行化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44296767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com