Юлия: Почему в этом цикле вспыхивает память? - PullRequest
1 голос
/ 03 апреля 2019

У меня есть некоторый многопоточный код, в котором каждый поток вызывает функцию f(df::DataFrame), которая читает столбец этого DataFrame и находит индексы, где столбец больше 0:

function f(df::DataFrame)
    X = df[:time]
    return findall(x->x>0, X)
end

Внутри основного потока я читаю в файле R * .rds, который Джулия преобразует в DataFrame, который я передаю f() следующим образом:

rds = "blabla.rds"
objs = load(rds);

params = collect(0.5:0.005:0.7)

for i in 1:length(objs)
    cols = [string(name) for name in names(objs.data[i]) if occursin("bla",string(name))]
    hypers = [(a,b) for a in cols, b in params] # length ~2000
    Threads.@threads for hi in 1:length(hypers) # MEMORY BLOWS UP HERE
        df = f(objs.data[i])
    end
end

Каждый df, передаваемый на f(), составляет примерно 0,7 ГБ. Анализируя использование памяти при запуске многопоточного цикла, потребление памяти увеличивается до ~ 30 ГБ. Есть 25 потоков и ~ 2000 вызовов на f(). Есть идеи, почему память взрывается?

ПРИМЕЧАНИЕ. Похоже, что проблему можно решить, вызывая GC.gc () внутри цикла время от времени, что выглядит как неудача ... ПРИМЕЧАНИЕ также: это происходит независимо от того, использую ли я обычный или многопоточный цикл.

EDIT: Профилировать код следующим образом:

function foo(objs)
    for i in 1:length(objs)
        df = objs.data[i]
        Threads.@threads for hi in 1:2000
            tmp = f(df)
        end
    end
end

@benchmark(foo($objs))

дает

BenchmarkTools.Trial: 
  memory estimate:  32.93 GiB
  allocs estimate:  48820
  --------------
  minimum time:     2.577 s (0.00% GC)
  median time:      2.614 s (0.00% GC)
  mean time:        2.614 s (0.00% GC)
  maximum time:     2.651 s (0.00% GC)
  --------------
  samples:          2
  evals/sample:     1
...