我得到的性能下降后,并行化的代码,计算图中心。图比较大,100K顶点。单线程应用程序大约需要7分钟。根据julialang站点(http://julia.readthedocs.org/en/latest/manual/parallel-computing/#man-parallel-computing)的建议,我修改了代码并使用pmap api来并行计算。我开始计算8个过程(julia-p 8calc_centrality.jl)。令我惊讶的是,我慢了10倍。并行过程现在需要一个多小时。我注意到并行进程初始化和开始计算需要几分钟。即使在所有8 html" target="_blank">CPU是0忙于julia应用程序,计算是超级慢。
任何关于如何提高并行性能的建议都将不胜感激。
calc_centrality.jl:
using Graphs
require("read_graph.jl")
require("centrality_mean.jl")
function main()
file_name = "test_graph.csv"
println("graph creation: ", file_name)
g = create_generic_graph_from_file(file_name)
println("num edges: ", num_edges(g))
println("num vertices: ", num_vertices(g))
data = cell(8)
data[1] = {g, 1, 2500}
data[2] = {g, 2501, 5000}
data[3] = {g, 5001, 7500}
data[4] = {g, 7501, 10000}
data[5] = {g, 10001, 12500}
data[6] = {g, 12501, 15000}
data[7] = {g, 15001, 17500}
data[8] = {g, 17501, 20000}
cm = pmap(centrality_mean, data)
println(cm)
end
println("Elapsed: ", @elapsed main(), "\n")
你的意思是中心性。jl
using Graphs
function centrality_mean(gr, start_vertex)
centrality_cnt = Dict()
vertex_to_visit = Set()
push!(vertex_to_visit, start_vertex)
cnt = 0
while !isempty(vertex_to_visit)
next_vertex_set = Set()
for vertex in vertex_to_visit
if !haskey(centrality_cnt, vertex)
centrality_cnt[vertex] = cnt
for neigh in out_neighbors(vertex, gr)
push!(next_vertex_set, neigh)
end
end
end
cnt += 1
vertex_to_visit = next_vertex_set
end
mean([ v for (k,v) in centrality_cnt ])
end
function centrality_mean(data::Array{})
gr = data[1]
v_start = data[2]
v_end = data[3]
n = v_end - v_start + 1;
cm = Array(Float64, n)
v = vertices(gr)
cnt = 0
for i = v_start:v_end
cnt += 1
if cnt%10 == 0
println(cnt)
end
cm[cnt] = centrality_mean(gr, v[i])
end
return cm
end
从Julia关于并行计算的页面:
Julia提供了一个基于消息传递的多处理环境,允许程序同时在不同内存域中的多个进程上运行。
如果我正确地解释这一点,Julia的并行性需要消息传递来同步进程。如果每个单独的进程只做很少的工作,然后进行消息传递,那么计算将被消息传递开销所主导,而不做任何工作。
我从你的代码中看不到,我也不太了解朱莉娅,看不到并行中断在哪里。但是你有一个很大的复杂的图,它可以随意地分布在多个过程中。如果他们需要在跨图链接时进行交互,你就会有这样的开销。
您可以通过将图的分区预先计算成大小大致相等、高度内聚的区域来修复它。我怀疑分手需要你已经想做的那种复杂的图形处理,所以你可能有一个鸡和蛋的问题要启动。
可能是朱莉娅给你提供了错误的并行模型。您可能需要一个共享地址空间,这样在图中行走的线程就不必使用消息来遍历弧。
下面是作者在评论中建议的带有@everywhere的代码https://stackoverflow.com/users/1409374/rickhg12hs.解决了性能问题!!!
test_parallel_pmap.jl
using Graphs
require("read_graph.jl")
require("centrality_mean.jl")
function main()
@everywhere file_name = "test_data.csv"
println("graph creation from: ", file_name)
@everywhere data_graph = create_generic_graph_from_file(file_name)
@everywhere data_graph_vertex = vertices(data_graph)
println("num edges: ", num_edges(data_graph))
println("num vertices: ", num_vertices(data_graph))
range = cell(2)
range[1] = {1, 25000}
range[2] = {25001, 50000}
cm = pmap(centrality_mean_pmap, range)
for i = 1:length(cm)
println(length(cm[i]))
end
end
println("Elapsed: ", @elapsed main(), "\n")
你的意思是中心性。jl
using Graphs
function centrality_mean(start_vertex::ExVertex)
centrality_cnt = Dict{ExVertex, Int64}()
vertex_to_visit = Set{ExVertex}()
push!(vertex_to_visit, start_vertex)
cnt = 0
while !isempty(vertex_to_visit)
next_vertex_set = Set()
for vertex in vertex_to_visit
if !haskey(centrality_cnt, vertex)
centrality_cnt[vertex] = cnt
for neigh in out_neighbors(vertex, data_graph)
push!(next_vertex_set, neigh)
end
end
end
cnt += 1
vertex_to_visit = next_vertex_set
end
mean([ v for (k,v) in centrality_cnt ])
end
function centrality_mean(v_start::Int64, v_end::Int64)
n = v_end - v_start + 1;
cm = Array(Float64, n)
cnt = 0
for i = v_start:v_end
cnt += 1
cm[cnt] = centrality_mean(data_graph_vertex[i])
end
return cm
end
function centrality_mean_pmap(range::Array{})
v_start = range[1]
v_end = range[2]
centrality_mean(v_start, v_end)
end
我猜这和平行无关。您的第二个centrality_mean
方法不知道什么类型的对象gr
,v_start
和v_end
。所以它将不得不为那个“外环”使用非优化的、缓慢的代码
虽然有几种可能的解决方案,但最简单的方法可能是分解从pmap
接收“命令”的函数:
function centrality_mean(data::Array{})
gr = data[1]
v_start = data[2]
v_end = data[3]
centrality_mean(gr, v_start, v_end)
end
function centrality_mean(gr, v_start, v_end)
n = v_end - v_start + 1;
cm = Array(Float64, n)
v = vertices(gr)
cnt = 0
for i = v_start:v_end
cnt += 1
if cnt%10 == 0
println(cnt)
end
cm[cnt] = centrality_mean(gr, v[i])
end
return cm
end
所有这些只是创建了一个中断,并给julia一个机会来优化第二部分(包含性能关键循环)的实际输入类型。
投的上海的高性能计算被挂了,被北京的高性能计算的语音技术部捞了 百度面试官非常好,体验感非常棒,奈何自己太菜了,全程道歉 一面 8.2 项目深挖 算子开发相关涉及知识点 GPU架构,内存模型 并发编程 锁 信号量 创建线程的几种方式 lambda表达式的底层是怎么实现的 std::move 使用场景,他比赋值构造好在哪 lock_guard相比较于lock/unlock能防止什么问题? cuda
问题内容: 我正在通过XML数据生成pdf文件。 我将段落元素的高度计算为: 但是这种方法不能正常工作。 你能给我个主意吗? 问题答案: 您的问题很奇怪。根据您的问题的标题,您想知道字符串的高度,但是您的代码显示您要求的是字符串的宽度。 请看一下FoobarFilmFestival示例。 如果是实例,则可以使用: 当我们使用12号字体时,这将返回基线以上的高度和基线以下的高度。您可能知道,字体大小
我有一个简单的任务:确定需要多少字节来将某个数字(字节数组长度)编码到字节数组并编码最终值(实现本文:编码长度和值字节)。 最初我写了一个快速完成任务的方法: 这是一段旧代码,编写方式很糟糕。 现在我正在尝试使用按位运算符或类来优化代码。这是按位版本的示例: 以及类的最终实现: 所有方法都按预期工作。我使用秒表类页面中的一个示例来衡量性能。性能测试让我惊讶。我的测试方法执行了1000次该方法的运行
我有一个包含一个。我想调整文本视图的大小,以便在给定固定宽度的情况下,显示整个字符串而不滚动。 有一个方法,允许为给定大小计算其边框 但不幸的是,它似乎不起作用,因为它总是返回单行的高度。
我正在研究一个基于代理的流行病模型。这个想法是单个代理根据他们在网络中观察到的情况(基于距离)做出决定。我在每个代理中都有几个功能,可以动态更新受感染接触者的数量,接触者表现出特定行为等。 下面的代码用于计算代理网络中受感染的联系人。 至少还有3个这样的函数可以保持表示代理网络中其他功能的其他代理的计数。现在,当我 有没有一种计算效率更高的方法来跟踪更大人口的网络统计数据?
我必须制作一个程序来找到显示n的最大方式!数字(不包括1)。 比如:4!= 1x2x3x4 = 1x2x3x2x2。所以你可以用5个数的乘积来表示4!。所以输入是4,输出是5。5是你能表达4的最大数量!。 简单地说,就是将一个阶乘数分解为素因子,计算出它们的个数并显示出来。 我所做的是一个“for”循环,在这个循环中我计算1到“n”的所有素因子及其数量。 但我对大数字有一个问题,比如当“n”是10