首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何并行化对称工人?

如何并行化对称工人?
EN

Stack Overflow用户
提问于 2015-03-27 14:25:20
回答 1查看 86关注 0票数 2

如果我有一个异步值work,需要并行复制和执行,以便耗尽用于线程执行的硬件功能,我将如何做到这一点?

例如,作为一个简短的具体例子,请考虑以下愚蠢的程序,它搜索小于1001的随机数:

代码语言:javascript
复制
let bound = ref System.Int32.MaxValue
let work = 
  async {
    let rand = new System.Random () 
    while !bound > 1000 do
      let x = rand.Next ()
      if x < !bound then
        bound := x
  }

[| work; work; work |] 
|> Async.Parallel
|> Async.RunSynchronously

(忽略bound的同步问题。)

在这里,我运行了三个工作人员;对于任何非零的数字,程序都是正确的;当工作人员的数量正好是可用的核心数时,可能更有效。如何更改此程序,以便根据可用核心的数量自动选择工作人员的数量?

更新.使用Async.Parallel并手动指示线程数是否是像上面那样并行处理CPU绑定计算的正确方法?如果不是,什么是?

EN

回答 1

Stack Overflow用户

发布于 2015-03-27 18:20:30

确定Process可用核数的一种方法如下:

代码语言:javascript
复制
let numberOfAvailableCores () : int =
    let p = System.Diagnostics.Process.GetCurrentProcess().ProcessorAffinity

    let rec countOnes acc = function
        | 0un -> acc
        | n -> 
            let i = int (n &&& 1un)
            countOnes (acc + i) (n >>> 1)

    countOnes 0 (unativeint p)

我发现这比System.Environment.ProcessorCount更准确,因为AFAIK没有考虑到ProcessorAffinity

Update:由于并行不公开函数来“并行”调用操作,所以可能的解决方案如下所示:

代码语言:javascript
复制
let numberOfAvailableCores () : int =
    let p = System.Diagnostics.Process.GetCurrentProcess().ProcessorAffinity

    let rec countOnes acc = function
        | 0un -> acc
        | n -> 
            let i = int (n &&& 1un)
            countOnes (acc + i) (n >>> 1)

    countOnes 0 (unativeint p)

let executeInParallel (a : unit->unit) : unit =
    let cores = numberOfAvailableCores ()

    let actions = 
        [|
            for x in 1..(cores * 2) -> Action a
        |]

    Parallel.Invoke actions

在尝试估计内核之间是否有任何争用时,只在1核上运行并将结果与“完整”核心解决方案进行比较可能是有用的。如果您有好的解决方案,那么在启用更多的核心时,您应该会看到一个线性的改进。仅在一个核心上运行的一种简单方法是设置ProcessorAffinity标志

代码语言:javascript
复制
let p = System.Diagnostics.Process.GetCurrentProcess ()
p.ProcessorAffinity <- 1n // Makes this process "single-core"

(我正竭力抗拒回答你没有问过的问题,但我仍然因流感而虚弱)

PS。F# Async在许多方面都很棒,但它们主要是为了解决响应性问题,而不是可伸缩性问题。这意味着,如果您使用大量的Async工作流组合,您可能会丢失宝贵的时钟周期。不过,你发布的例子不会受到影响。对于与CPU绑定的问题,我倾向于使用Parallel,因为它使用自动缩放和工作窃取来利用所有的CPU资源,同时具有较低的开销。Taskhopac也是很好的替代品。

PS。如果你想自己管理缩放,我相信经验法则是核心数量的两倍。

PS。您说过忽略bound的同步问题,这是公平的,但我只想指出,如果一个共享资源经常被所有核心访问,那么性能可能不会有多大提高。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29303027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档