【问题标题】:Julia parallel computing for loopJulia 并行计算 for 循环
【发布时间】:2019-03-13 17:06:33
【问题描述】:

我想从一个大的上三角矩阵计算元素的总和。常规的 Julia 代码如下。

function upsum(M); n = size(M)[1]; sum = 0
    for i = 1:n-1 for j = i+1:n
        sum = sum + M[i,j]
        end
    end
    return sum
end

R = randn(10000,10000)
upsum(R)

由于矩阵很大,我想知道有没有办法提高速度。如何在这里使用并行计算?

【问题讨论】:

标签: parallel-processing julia


【解决方案1】:

在这种情况下,我会使用线程而不是并行处理。这是一个示例代码:

using Base.Threads

function upsum_threads(M)
    n = size(M, 1)
    chunks = nthreads()
    sums = zeros(eltype(M), chunks)
    chunkend = round.(Int, n * sqrt.((1:chunks) ./ chunks))
    @assert minimum(diff(chunkend)) > 0
    chunkstart = [2; chunkend[1:end-1] .+ 1]
    @threads for job in 1:chunks
        s = zero(eltype(M))
        for i in chunkstart[job]:chunkend[job]
            @simd for j in 1:(i-1)
                @inbounds s += M[j, i]
            end
        end
        sums[job] = s
    end
    return sum(sums)
end

R = randn(10000,10000)
upsum_threads(R)

它应该会给你一个显着的加速(即使你删除 @threads 它应该会快得多)。

您可以通过设置 JULIA_NUM_THREADS 环境变量来选择 Julia 使用的线程数。

【讨论】:

  • 非常感谢您的帮助!我还有一个问题,如果我还想同时计算大上三角矩阵中每个元素的平方和怎么办。我试过@inbounds s += M[j, i] @inbounds sq += M[j, i]^2,它有效。有没有更好的方法来做到这一点?
  • 两个内部循环可能比一个内部循环中的两个操作更好,因为我认为@simd 应该可以工作(但是如果这两种设计之间有任何显着差异,您必须进行基准测试) .
  • 感谢您的回复!你的意思是最好有两个@threads for job in 1:chunks
  • 我的意思是 inner 循环 @simd for j in 1:(i-1),因为那时 M[j,i] 应该仍然在 CPU 缓存中(但我没有对其进行基准测试,所以复制了 最外层 循环可能不会明显变慢)。
猜你喜欢
  • 2020-09-10
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多