并行代码CPU利用率问题


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(("中使用">计算(("运行应用程序,我会看到CPU利用率为70-80%。

但与">abc(("中的">compution1(("代码相同,我看到只有20%的CPU利用率,并且我看到许多(一半的内核(内核处于空闲状态。

有人知道这种行为吗?

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

使用探查器应该很容易找到,但在这种情况下,答案很明显:

Convert.ToString

将大大限制您的性能,使其绑定到内存,(可能更重要的是(绑定到堆/GC。

computation几乎是纯CPU工作。computation1在执行的每一步都使用堆,这意味着频繁的内存访问(事实上,它甚至不能很好地使用CPU缓存,尽管GC压缩会抵消这一点(,并经常在堆上分配和收集字符串。堆和GC的性能相当高,但每秒有数百万/数十亿个字符串在推动它。大多数时候,你的代码会因为GC正在运行而挂起。

最新更新