@julia中的并行循环与本机循环

@julia中的并行循环与本机循环,julia,Julia,我运行了一些示例,得到了一些结果。对于大量的迭代,我们可以得到一个好的结果,但是对于较少的迭代,我们可以得到一个更差的结果 我知道有一点开销,这是绝对可以的,但有没有任何方法可以运行一些循环,以较少的迭代量并行方式优于顺序方式 x = 0 @time for i=1:200000000 x = Int(rand(Bool)) + x end 7.503359秒(200.00 M分配:2.980 GiB,2.66%gc时间) 0.432549秒(3.91K分配:241.138千磅) 我在

我运行了一些示例,得到了一些结果。对于大量的迭代,我们可以得到一个好的结果,但是对于较少的迭代,我们可以得到一个更差的结果

我知道有一点开销,这是绝对可以的,但有没有任何方法可以运行一些循环,以较少的迭代量并行方式优于顺序方式

x = 0
@time for i=1:200000000
    x = Int(rand(Bool)) + x
end
7.503359秒(200.00 M分配:2.980 GiB,2.66%gc时间)

0.432549秒(3.91K分配:241.138千磅)

我在这里得到了很好的并行结果,但在下面的例子中没有

x2 = 0
@time for i=1:100000
    x2 = Int(rand(Bool)) + x2
end
0.006025秒(98.97 k分配:1.510 MiB)


0.084736秒(3.87 k分配:239.122 KiB)

Q:有没有办法以并行方式比顺序方式运行迭代量更少的循环

x = 0
@time for i=1:200000000
    x = Int(rand(Bool)) + x
end

A:

1)如果这一切都有意义的话,就获取更多的资源(要计算的处理器,要存储的内存)

2)更智能地安排工作流-为了从基于寄存器的代码中获益,从每次首次提取时利用缓存线的大小中获益,尽可能地部署重用(艰苦的工作?是的,这是艰苦的工作,但为什么要重复支付150+[ns],而不是一次性支付,并在大约30秒内重用对齐的相邻单元[ns]延迟成本(如果NUMA允许)?)。更智能的工作流通常还意味着代码重新设计,以增加生成的汇编代码计算的“密度”,并调整代码以更好地绕过(优化-)-超标量处理器硬件设计技巧,在高度调优的HPC计算有效负载中没有任何用处/积极的好处

3)避免任何阻塞资源和瓶颈(中心奇点类似于主机硬件的唯一随机性源、IO设备等)

4)熟悉优化编译器的内部选项和“快捷方式”——有时生成反模式会以延长运行时间为代价


5)最大限度地利用底层操作系统的调整。如果不这样做,优化后的代码仍在等待(而且还有很多)在O/S-scheduler的队列中

并行处理总是效率较低。这是因为并行处理总是会增加同步的开销。无论如何,希望是,与纯粹的顺序调用(一台计算机,单核)相比,提前在墙上得到结果

你的数字惊人,我找到了原因

首先,允许使用所有内核,转到REPL

julia> nworkers
4

# original case to get correct relative times
julia> x = 0
julia> @time for i=1:200000000
          x = Int(rand(Bool)) + x
       end

7.864891 seconds (200.00 M allocations: 2.980 GiB, 1.62% gc time)

julia> x = @time @parallel (+) for i=1:200000000
          Int(rand(Bool))
       end
0.350262 seconds (4.08 k allocations: 254.165 KiB)
99991471

# now a correct benchmark
julia> function test()
         x = 0
         for i=1:200000000
           x = Int(rand(Bool)) + x
         end
       end
julia> @time test()
0.465478 seconds (4 allocations: 160 bytes)
发生了什么事?

您的第一个测试用例使用了一个全局变量x。这是非常慢的。这个用例访问一个慢变量2000000次

在第二个测试用例中,全局变量x只分配了一次,因此不考虑性能差


在我的测试用例中没有全局变量。我使用了一个局部变量。局部变量更快(由于更好的编译器优化)

我想在经过一定数量的线程之后,使用线程的开销是值得的iterations@MauricePerry这不是线程,而是多处理。多处理的开销比线程大得多,因为它是完全异步的,甚至可以在其他计算机上有进程。@ReD您需要“足够”在每个进程上进行多处理以获得回报。否则,您应该通过
线程来使用线程。@threads
。您介意先使用一些术语吗?这不是[Parallel]-进程执行,而是[Concurrent]-调度——正如定义的那样(cit:)-[Parallel]处理与[Concurrent]处理形成鲜明对比处理,保证以并行方式启动/执行/完成所有线程级和/或指令级任务,并保证同时执行的代码路径的完成。如果是真正的[并行]执行,应该有200E+6个CPU核来允许这种[并行]-执行。不在这里,@parallel decorator从不创建CPUs@ReD有关(
SEQ
:设置开销,
PAR
:HPC有效载荷)加速的详细信息,请毫不犹豫地查看一篇关于(开销感知的)Amdahl法则+收益递减点数据的帖子,如>>中类似动机问题的可实现加速所述
julia> nworkers
4

# original case to get correct relative times
julia> x = 0
julia> @time for i=1:200000000
          x = Int(rand(Bool)) + x
       end

7.864891 seconds (200.00 M allocations: 2.980 GiB, 1.62% gc time)

julia> x = @time @parallel (+) for i=1:200000000
          Int(rand(Bool))
       end
0.350262 seconds (4.08 k allocations: 254.165 KiB)
99991471

# now a correct benchmark
julia> function test()
         x = 0
         for i=1:200000000
           x = Int(rand(Bool)) + x
         end
       end
julia> @time test()
0.465478 seconds (4 allocations: 160 bytes)