Julia 朱莉娅:为什么记忆会在这个循环中爆炸?

Julia 朱莉娅:为什么记忆会在这个循环中爆炸?,julia,Julia,我有一些多线程代码,其中每个线程调用一个函数f(df::DataFrame),该函数读取该数据帧的一列并查找该列大于0的索引: function f(df::DataFrame) X = df[:time] return findall(x->x>0, X) end 在主线程中,我读取了一个R*.rds文件,Julia将其转换为一个数据帧,并将其传递给f(),如下所示: rds = "blabla.rds" objs = load(rds); params = c

我有一些多线程代码,其中每个线程调用一个函数
f(df::DataFrame)
,该函数读取该数据帧的一列并查找该列大于0的索引:

function f(df::DataFrame)
    X = df[:time]
    return findall(x->x>0, X)
end
在主线程中,我读取了一个R*.rds文件,Julia将其转换为一个数据帧,并将其传递给
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
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))
传递给
f()
的每个
df
大约为0.7GB。分析运行多线程循环时的内存使用情况,内存使用情况会上升到~30GB。有25个线程和~2000个对
f()
的调用。知道为什么记忆会爆炸吗

注意:通过每隔一段时间在循环中调用GC.GC(),这个问题似乎得到了改善,这似乎是一个错误。。。 另外请注意:无论我是否使用常规循环或多线程循环,都会发生这种情况

编辑: 按如下方式分析代码:

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
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))
给予


也许我错了,但似乎围绕茱莉亚的所有炒作都是毫无根据的。由于启动时间太慢,您无法将其作为脚本运行,并且在每次循环迭代后您都必须进行自己的垃圾收集,这确实会降低运行速度。似乎它不会很快取代python。这似乎是一个非常奇怪的评论。您通常需要运行自己的垃圾收集,这肯定不是真的。我从未经历过。Julia的线程模型仍在开发中,顺便说一句。无论我是否使用多线程或常规循环,都会发生这种情况。您是否在全局范围内对此进行基准测试/分析?您可以尝试将其包装到函数中并对其进行分析吗?另外,重新编写此调用:
findall(X.>0)
findall(X->X>0,X)
。前者做了很多不必要的分配。也许我错了,但似乎围绕朱莉娅的所有炒作都是毫无根据的。由于启动时间太慢,您无法将其作为脚本运行,并且在每次循环迭代后您都必须进行自己的垃圾收集,这确实会降低运行速度。似乎它不会很快取代python。这似乎是一个非常奇怪的评论。您通常需要运行自己的垃圾收集,这肯定不是真的。我从未经历过。Julia的线程模型仍在开发中,顺便说一句。无论我是否使用多线程或常规循环,都会发生这种情况。您是否在全局范围内对此进行基准测试/分析?您可以尝试将其包装到函数中并对其进行分析吗?另外,重新编写此调用:
findall(X.>0)
findall(X->X>0,X)
。前者进行了大量不必要的分配。