为什么下面的并行阵列版本比常规版本慢
Why is the parallel array version of the below slower than the regular one
我正在研究使用多核加速大型数据集的处理。下面的测试代码产生了一个令人惊讶的结果,即并行代码版本比单核实现慢大约 3 倍。为什么会这样?
[<EntryPoint>]
let main argv =
let n = 200000000
let xs = [|1..n|]
let stopWatch = System.Diagnostics.Stopwatch()
stopWatch.Start()
let ys1 = xs |> Array.map (fun x -> x * 10)
stopWatch.Stop()
printfn "%A" stopWatch.Elapsed
System.GC.Collect(2)
let stopWatch = System.Diagnostics.Stopwatch()
stopWatch.Start()
let ys2 = xs |> Array.Parallel.map (fun x -> x * 10)
stopWatch.Stop()
printfn "%A" stopWatch.Elapsed
printfn "%A" argv
0 // return an integer exit code
结果如下:
00:00:00.3471365
00:00:00.9448111
[||]
Press any key to continue . . .
我已将编译选项设置为首选优化的 64 位应用程序。
更新
根据下面的建议,我将 lambda 函数更改为类似于 exp(100.78 + sin x + 89.6*log x)
的更复杂的函数,并得到了预期的结果 - 并行要快得多。
当您执行并行时,每个任务都会有一些开销,例如,每个任务都必须分派到一个线程,然后收集结果。
在系列中,开销要少得多。
当任务像x*10
一样简单时。开销占主导地位。
对于更复杂的任务,并行会更快
我正在研究使用多核加速大型数据集的处理。下面的测试代码产生了一个令人惊讶的结果,即并行代码版本比单核实现慢大约 3 倍。为什么会这样?
[<EntryPoint>]
let main argv =
let n = 200000000
let xs = [|1..n|]
let stopWatch = System.Diagnostics.Stopwatch()
stopWatch.Start()
let ys1 = xs |> Array.map (fun x -> x * 10)
stopWatch.Stop()
printfn "%A" stopWatch.Elapsed
System.GC.Collect(2)
let stopWatch = System.Diagnostics.Stopwatch()
stopWatch.Start()
let ys2 = xs |> Array.Parallel.map (fun x -> x * 10)
stopWatch.Stop()
printfn "%A" stopWatch.Elapsed
printfn "%A" argv
0 // return an integer exit code
结果如下:
00:00:00.3471365
00:00:00.9448111
[||]
Press any key to continue . . .
我已将编译选项设置为首选优化的 64 位应用程序。
更新
根据下面的建议,我将 lambda 函数更改为类似于 exp(100.78 + sin x + 89.6*log x)
的更复杂的函数,并得到了预期的结果 - 并行要快得多。
当您执行并行时,每个任务都会有一些开销,例如,每个任务都必须分派到一个线程,然后收集结果。
在系列中,开销要少得多。
当任务像x*10
一样简单时。开销占主导地位。
对于更复杂的任务,并行会更快