Julia 多线程:如何控制变量的局部范围

ste*_*onB 2 multithreading julia

我对 Julia 相当陌生,我正在尝试使用 Julia 的多线程功能。

下面是我为探索 Julia 能力而制作的一个玩具示例。这是我正在尝试做的事情的一个非常简化的版本。我需要并行化循环。在这个循环中,我正在执行一些需要缓冲区数组的计算(在下面的示例中,缓冲区当然是不必要的)。此外,缓冲区不能在线程之间共享,因为这会导致竞争条件。

我正在使用宏 @threads 来并行化我的循环。问题是我找不到一种方法来定义不同线程应如何与 buf 数组交互:

  • 有没有办法定义数组是否应该共享或者每个线程都有其如何复制。例如,它在 OpenMP 中使用私有或共享变量声明系统的工作方式?
  • 在循环中初始化数组不是一个选项,因为它将在每个步骤中创建重新分配内存,而不是为每个线程一次。
  • 是否有更适合此类应用程序的不同 Julia 库?
function calcparallel(buf::AbstractArray,result::AbstractArray)

   @threads for i=1:length(result) 
        buf[1] = float(i)         
        buf[2] = 1.0/float(i) 
        buf[3] = sqrt(i)

        result[i] = buf[1] * buf[3] + buf[2]

    end
    return result 
end

n = 1000
nn = 10
buf2 = zeros(Float64,nn)
result2  = zeros(Float64,n)


@time calcparallel(buf2,result2)
Run Code Online (Sandbox Code Playgroud)

jli*_*ing 6

必须阅读: https: //julialang.org/blog/2023/07/PSA-dont-use-threadid/

您需要:static从 Julia 1.8 开始,因为默认值更改为:dynamic,但请阅读上面的官方 PSA 博客文章以获得更好的模式。

线程本地缓冲区的模式是这样的:

function calcparallel(buf::AbstractArray,result::AbstractArray)
   bufs = [zeros(3) for _ in Threads.nthreads()]
   @threads :static for i=1:length(result) 
        buf = bufs[Threads.threadid()]
        buf[1] = float(i)         
        buf[2] = 1.0/float(i) 
        buf[3] = sqrt(i)

        result[i] = buf[1] * buf[3] + buf[2]

    end
    return result 
end

Run Code Online (Sandbox Code Playgroud)