如何在Julia中跨多个内核拆分读取的文件?

时间:2018-10-10 18:45:49

标签: julia

我要解析的本地计算机上有一个相对较大的文件(〜10 GB):对于其中包含字符串"bobby"的每一行,我想将整行存储在数组。这是我最初的尝试:

function runner()
    io = open("large_10gb_file.txt", "r")
    data = []
    for line in eachline(io)
        if occursin("bobby", line)
            push!(data, line)
        end
    end
    close(io)
    return data
end

这很好用。但是,我看到当我调用runner()时,它使用一个CPU内核(利用率为100%);我在笔记本电脑上可以使用5个以上的CPU内核-如何修改代码才能做到这一点?实际上,这样做是否有意义,因为文件可能是IO绑定在我的NVMe SSD上,而不是CPU绑定了?

这是我最初的并行化尝试:

function runner()
    io = open("large_10gb_file.txt", "r")
    data = []
    @distributed for line in eachline(io)
        if occursin("bobby", line)
            push!(data, line)
        end
    end
    close(io)
    return data
end

但是,上面的方法返回一个空(0元素)数组。因此,我添加了@sync来同步线程并保证返回顺序:

function runner()
    io = open("large_10gb_file.txt", "r")
    data = []
    @sync @distributed for line in eachline(io)
        if occursin("bobby", line)
            push!(data, line)
        end
    end
    close(io)
    return data
end

但是,这将返回错误:

ERROR: MethodError: no method matching length(::Base.EachLine{IOStream})
Closest candidates are:
  length(::Core.SimpleVector) at essentials.jl:571
  length(::Base.MethodList) at reflection.jl:728
  length(::Core.MethodTable) at reflection.jl:802
  ...
(::getfield(Distributed, Symbol("##169#171")){getfield(Main, Symbol("##9#10")){Array{Any,1}},Base.EachLine{IOStream}})() at ./task.jl:244
Stacktrace:
 [1] sync_end(::Array{Any,1}) at ./task.jl:226
 [2] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/Distributed/src/macros.jl:337 [inlined]
 [3] macro expansion at ./task.jl:244 [inlined]
 [4] runner() at ./REPL[73]:4
 [5] top-level scope at none:0

我不熟悉Julia(昨天才刚开始学习语法),但是似乎eachline调用没有与length匹配的方法,因此{{1 }}无法准确地划分不同工作人员之间的工作。

注意:在运行@distributed for之前,我确实做了addprocs(4),之后@distributed for开始返回procs()

0 个答案:

没有答案