并行代码CPU利用率问题

时间:2015-06-30 09:49:17

标签: f# task-parallel-library

open System
open System.Diagnostics
open System.Threading.Tasks
open System.Collections

let computation input =
  input|> Array.map (fun x-> sqrt(float x))|> ignore

let computation1 (input:int[]) =
  input|> Array.map (fun x-> Convert.ToString(x,2)) |> ignore


let abc p = 

        for i in 1..50000 do
            [|for i in 1..100000 -> i|]
            |> computation 

Parallel.For(0,100,fun x->abc 0) |>ignore

您好, 在上面的程序中,如果我在“ abc()”中使用“ computation()”运行应用程序,我看到CPU利用率为70-80%。

但是在“ abc()”中使用“ computation1()”的代码相同,我只看到20%的CPU利用率,而且我看到很多(核心的一半)核心闲置。

有没有人知道这种行为?

我的CPU规格: Intel Xeon CPU @ 3.40Hz,启用超线程 总核心数:2个CPU,每个核心数为8个核心= 16个 HT = 2 * 16 = 32

的总核心数

1 个答案:

答案 0 :(得分:5)

使用分析器很容易找到,但在这种情况下答案是显而易见的:

Convert.ToString

将大大限制你的性能,使其受内存限制,并且(可能更重要的是)堆/ GC绑定。

computation几乎是纯粹的CPU工作。 computation1使用堆来执行每一步 - 这意味着频繁的内存访问(事实上,它甚至不能很好地使用CPU缓存,尽管GC压缩可以抵消这一点),并经常分配和收集字符串在堆上。堆和GC的性能非常高,但每秒数百万/十亿字符串才真正推动它。大多数情况下,由于GC正在运行,您的代码将被暂停。