天道酬勤,学无止境

Julia: How to profile parallel code

Whats an appropriate way to profile parallel code in julia? When I run

@profile foo(...) 

where foo is my function, I get

julia> Profile.print()
1234 task.jl; anonymous; line: 23
 4    multi.jl; remotecall_fetch; line: 695
  2 multi.jl; send_msg_; line: 172
   2 serialize.jl; serialize; line: 74
    2 serialize.jl; serialize; line: 299
     2 serialize.jl; serialize; line: 130
      2 serialize.jl; serialize; line: 299
       1 dict.jl; serialize; line: 369
        1 serialize.jl; serialize_type; line: 278
       1 serialize.jl; serialize; line: 199
        1 serialize.jl; serialize; line: 227
         1 serialize.jl; serialize; line: 160
          1 serialize.jl; serialize; line: 160
           1 serialize.jl; serialize; line: 299
            1 serialize.jl; serialize; line: 294
             1 io.jl; write; line: 47
              1 ./iobuffer.jl; write; line: 234
               1 ./iobuffer.jl; ensureroom; line: 151
                1 ./array.jl; resize!; line: 503
  2 multi.jl; send_msg_; line: 178
   2 stream.jl; write; line: 724
 1230 multi.jl; remotecall_fetch; line: 696
  1230 ./multi.jl; wait_full; line: 595
   1230 ./task.jl; wait; line: 189
    1229 ./task.jl; wait; line: 269
     1229 ./stream.jl; process_events; line: 529
    1    ./task.jl; wait; line: 282
     1 ./stream.jl; process_events; line: 529
402  task.jl; anonymous; line: 95
 402 REPL.jl; eval_user_input; line: 53
  401 profile.jl; anonymous; line: 14
   401 ...mba/src/model/mcmc.jl; mcmc; line: 314
    401 ./task.jl; sync_end; line: 306
     401 task.jl; wait; line: 48
      401 ./task.jl; wait; line: 189
       401 ./task.jl; wait; line: 269
        401 ./stream.jl; process_events; line: 529
  1   profile.jl; anonymous; line: 16
217  task.jl; task_done_hook; line: 83
 217 ./task.jl; wait; line: 269
  217 ./stream.jl; process_events; line: 529

评论

Don't know if it will work, but you might want to consider having the workers call a function that looks something like this:

function profile_function(func, args...)
    Profile.clear()
    ret = @profile apply(func, args)
    pdata = Profile.retrieve()
    ret, pdata
end

pdata should contain the profiling data from that worker. You should be able to view it in ProfileView.

You may try VTune Amplifier (https://software.intel.com/en-us/intel-vtune-amplifier-xe) to profile Julia code at function level as described at https://software.intel.com/en-us/blogs/2013/10/10/profiling-julia-code-with-intel-vtune-amplifier. You may also need to apply a patch to LLVM (https://gist.github.com/ArchRobison/d3601433d160b05ed5ee) to workaround source level performance information bug to get correct data at a source line level

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Julia: Parallel code slower than Sequential code, are there alternatives to remotecall()?
    When I run in parallel a simple function (with different inputs per worker) the time it takes for a parallelized version code is consistently longer than if it was sequential. The simple function is addprocs(2) @everywhere function simple(i,Q,vt_0,ct_0) a=sum((rand(1:i),vt_0,ct_0))*2 return a end The Parallelized version of my code is #In Parallel tic() N=10000; v=zeros(N); c=zeros(N); vt_0=0; ct_0=0; for i=1:N v[i]=fetch(remotecall(simple,2,i,1,vt_0,ct_0)) c[i]=fetch(remotecall(simple,3,i,2,vt_0,ct_0)) vt_0=v[i] ct_0=c[i] end toc() While the sequential code would be just calling the function
  • 如何以及何时在Julia中使用@async和@sync(How and When to Use @async and @sync in Julia)
    问题 我已经阅读了@async和@sync宏的文档,但仍然无法弄清楚如何以及何时使用它们,也无法在Internet上的其他地方找到许多关于它们的资源或示例。 我的近期目标是找到一种方法来设置多个工作人员并行执行工作,然后等到他们全部完成我的代码后再进行工作。 这篇文章:等待在Julia中的远程处理器上完成任务包含一种成功的方法。 我曾经以为可以使用@async和@sync宏,但是我最初的失败是想知道我是否正确理解了如何以及何时使用这些宏。 回答1 根据?@async下的文档,“ @async将表达式包装在Task中。” 这意味着,对于处于其范围内的任何内容,Julia都会开始运行此任务,然后继续执行脚本中的下一个内容,而无需等待任务完成。 因此,例如,没有宏,您将得到: julia> @time sleep(2) 2.005766 seconds (13 allocations: 624 bytes) 但是使用宏,您将获得: julia> @time @async sleep(2) 0.000021 seconds (7 allocations: 657 bytes) Task (waiting) @0x0000000112a65ba0 julia> 因此,Julia允许脚本继续执行(并使@time宏完全执行),而无需等待任务(在本例中为休眠状态,等待两秒钟)完成。 相比之下,
  • Julia parallel programming - Making existing function available to all workers
    I am faced with the following problem: I have a function called TrainModel that runs for a very long time on a single thread. When it finishes computing, it returns a function as an output argument, let's call it f. When I enquire the type of this f, Julia returns: (generic function with 1 method) (I am not sure of this last piece of information is useful to anyone reading this) Now in a second step, I need to apply function f on a very large array of values. This is a step that I would like to parallelise. Having had started Julia with multiple processes, e.g. julia -p 4 ideally, I would use
  • 术语“向量化”在不同上下文中是否意味着不同的事物?(Does the term “vectorization” mean different things in different contexts?)
    问题 根据我之前阅读的内容,矢量化是一种并行化形式,称为SIMD。 它允许处理器在阵列上同时执行相同的指令(例如加法)。 但是,当阅读有关Julia和R的矢量化性能的“矢量化和反矢量化代码之间的关系”时,我感到困惑。 该帖子声称,经过向量化的Julia代码(通过循环)比在Julia和R中的向量化代码更快,因为: 这使一些不熟悉R的内部结构的人感到困惑。因此,值得注意的是如何提高R代码的速度。 提高性能的过程非常简单:首先从解矢量化的R代码开始,然后用矢量化的R代码替换它,然后最终在解矢量化的C代码中实现此矢量化的R代码。 遗憾的是,对于许多R用户而言,最后一步是看不见的,因此他们将向量化本身视为提高性能的一种机制。 向量化本身并不能帮助提高代码速度。 使R中的向量化有效的原因在于,它提供了一种将计算移入C的机制,其中,向量化的隐藏层可以发挥其魔力。 它声称R将用R编写的矢量化代码转换为C中的去矢量化代码。如果矢量化更快(作为并行化的一种形式),为什么R会对代码进行去矢量化,为什么加号呢? 回答1 R中的“向量化”是R解释器认为的向量处理。 以函数cumsum为例。 进入时,R解释器看到向量x传递到此函数中。 但是,该工作随后传递给R解释器无法分析/跟踪的C语言。 C在工作时,R在等待。 在R的解释器恢复工作时,已经处理了向量。 因此,在R看来,它发出了一条指令,但处理了一个向量。
  • If a Julia script is run from the command line, does it need to be re-compiled every time?
    I've read through quite some documentation and questions but I'm still confused about this. In the Profiling section of the documentation it's suggested to first run the target function in the REPL once, so that it's already compiled before being profiled. However, what if the script is fairly complicated and is inteded to be run in the command line, taking arguments? When the julia process finishes and I run the script the second time, is the compilation performed again? Posts like https://stackoverflow.com/a/42040763/1460448, Julia compiles the script every time? give conflicting answers
  • Does the term “vectorization” mean different things in different contexts?
    Based on what I've read before, vectorization is a form of parallelization known as SIMD. It allows processors to execute the same instruction (such as addition) on an array simultaneously. However, I got confused when reading The Relationship between Vectorized and Devectorized Code regarding Julia's and R's vectorization performance. The post claims that devectorized Julia code (via loops) is faster than the vectorized code in both Julia and R, because: This confuses some people who are not familiar with the internals of R. It is therefore worth noting how one improves the speed of R code
  • How and When to Use @async and @sync in Julia
    I have read the documentation for the @async and @sync macros but still cannot figure out how and when to use them, nor can I find many resources or examples for them elsewhere on the internet. My immediate goal is to find a way to set several workers to do work in parallel and then wait until they have all finished to proceed in my code. This post: Waiting for a task to be completed on remote processor in Julia contains one successful way to accomplish this. I had thought it should be possible using the @async and @sync macros, but my initial failures to accomplish this made me wonder if I am
  • Julia: why doesn't shared memory multi-threading give me a speedup?
    I want to use shared memory multi-threading in Julia. As done by the Threads.@threads macro, I can use ccall(:jl_threading_run ...) to do this. And whilst my code now runs in parallel, I don't get the speedup I expected. The following code is intended as a minimal example of the approach I'm taking and the performance problem I'm having: [EDIT: See later for even more minimal example] nthreads = Threads.nthreads() test_size = 1000000 println("STARTED with ", nthreads, " thread(s) and test size of ", test_size, ".") # Something to be processed: objects = rand(test_size) # Somewhere for our
  • Julia, run function multiple times, save results in array
    I am building a microsimulation model in Julia. I have built the structure of my function and it runs great for for 1 "person". I'd like to write the script to run 100000+ people through the model and save the results in one location. Eventually I'd like to execute this in parallel. Below I have included a simple working version of the code with dummy probabilities. using Distributions # Microsim function function MicroSim(start_age, stages) stage = 0 age = start_age # Set all trackers to 0 Death_tracker = 0 Disease_tracker = 0 # While loop while stage <= stages age = age #####################
  • 如何在Julia中导入自定义模块(How to import custom module in julia)
    问题 我在这里写了一个模块: # Hello.jl module Hello function foo return 1 end end 和 # Main.jl using Hello foo() 当我运行Main模块时: $ julia ./Main.jl 我收到此错误: ERROR: LoadError: ArgumentError: Hello not found in path in require at ./loading.jl:249 in include at ./boot.jl:261 in include_from_node1 at ./loading.jl:320 in process_options at ./client.jl:280 in _start at ./client.jl:378 while loading /Main.jl, in expression starting on line 1 回答1 在using Hello之前,您应该include("./Hello.jl") 回答2 自Julia v0.7和v1.0发行以来,这个问题有了新的答案,略有不同。 我只需要这样做,就可以将发现的信息发布在这里。 正如其他解决方案中已经解释的那样,有必要包括定义模块的相关脚本。 但是,由于自定义模块不是软件包
  • How to load ~/.bash_profile when entering bash from within zsh?
    I've used bash for two years, and just tried to switch to zsh shell on my OS X via homebrew. And I set my default (login) shell to zsh, and I confirmed it's set properly by seeing that when I launch my Terminal, it's zsh shell that is used in default. However, when I try to enter bash shell from within zsh, it looks like not loading ~/.bash_profile, since I cannot run my command using aliases, which is defined in my ~/.bash_profile like alias julia="~/juila/julia", etc.. Also, the prompt is not what I set in the file and instead return bash-3.2$. For some reasons, when I set my login shell to
  • @parallel和pmap到底有什么区别?(What exactly is the difference between @parallel and pmap?)
    问题 如标题所述: @parallel和pmap到底有什么区别? 我不是说明显的一个宏是一个循环,另一个是在函数上工作,我的意思是它们的实现有什么确切的区别,我该如何利用这些知识在它们之间进行选择? 我问的原因是,我编写的许多应用程序都可以使用以下一种结构:我可以编写一个循环并使用@parallel计算某些@parallel ,或者将循环中的内容包装到函数中并在其上调用pmap 。 我一直遵循以下建议:使用@parallel进行快速评估的事情,使用pmap进行调用,每个任务花费更长的时间(如文档中所述),但是我觉得如果我对它的工作有了更好的了解我可以做出更好的选择。 例如: @parallel在评估之前将工作分开? 我注意到,如果我运行一个并行循环,其中每个内部调用花费随机的时间, @parallel可能要花费很长时间,因为最后我仍然只有很少的进程在工作。 在相同的微测试上的pmap似乎没有: pmap根据需要重新分配工作? 诸如此类的其他问题都源于我对pmap与@parallel到底有何不同的@parallel 。 回答1 @parallel需要做的工作,divy起来可用的工人当中的时候了。 注意,在?@parallel我们得到The specified range is partitioned ... across all workers. 相比之下,
  • Java 8中findAny()和findFirst()之间的区别(Difference between findAny() and findFirst() in Java 8)
    问题 我对Java 8中Stream API的Stream#findAny()和Stream#findFirst()有点困惑。 我了解的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素? 那么,为什么要用两种方法完成同一任务? 我想念什么吗? 回答1 我了解到的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素? 这不是真的。 根据javadoc,Stream#findAny(): 返回一个Optional<T>描述流的一些元件或空Optional<T>如果流是空的。 该操作的行为明确地是不确定的。 可以自由选择流中的任何元素。 这是为了在并行操作中获得最佳性能。 而Stream.findFirst()将返回Optional<T>严格描述流的第一个元素。 Stream类没有.findOne()方法,因此我想您的意思是.findFirst() 。 回答2 不,两者都不会返回Stream的第一个元素。 从Stream.findAny()(强调我的): 返回一个Optional描述流的一些元件,或一个空Optional如果流是空的。 这是短路端子的操作。 该操作的行为明确地是不确定的。 可以自由选择流中的任何元素。 这是为了在并行操作中获得最佳性能。 代价是对同一源的多次调用可能不会返回相同的结果。 (如果需要稳定的结果,请改用findFirst
  • pip安装numpy的问题-RuntimeError:断开的工具链:无法链接简单的C程序(Problems with pip install numpy - RuntimeError: Broken toolchain: cannot link a simple C program)
    问题 我正在尝试将numpy(以及scipy和matplotlib)安装到virturalenv中。 我一直收到这些错误: RuntimeError: Broken toolchain: cannot link a simple C program ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 我已经安装了用于xcode的命令行工具 $ which gcc /usr/bin/gcc $ which cc /usr/bin/cc 我在Mac OSX 10.9上使用Brew安装的python 编辑是的,尝试使用pip安装。 整个回溯是巨大的(> 400行) 这是其中的一部分: C compiler: cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes
  • 读芯术python_Python仍是人工智能和机器学习的主导编程语言吗?
    上世纪90年代初,Python面世了。近30年来,关于它的“炒作”一直没有少过。当然,编程界花了至少20年的时间才认识到它,但自那以后,它的流行程度远远超过了C、C#、Java甚至Javascript。 尽管Python目前在数据科学和机器学习领域,以及某些程度上在科学和数学计算领域占据着主导地位,但与Julia,Swift和Java等新语言相比,它确实有其劣势。 是什么让Python如此受欢迎? Python迅速发展的主要原因是易于学习和功能强大。这使得它对初学者,包括那些由于C、C++等语言语法艰涩且陌生而对其望而却步的人,都非常有吸引力。 该语言从根本上广泛强调代码的可读性。凭借其简洁而富有表现力的语法,它允许开发人员在不编写大量代码的情况下表达想法和概念(例如在C或Java等低级语言)。Python非常简单,可以与其他编程语言无缝集成(例如将CPU密集型任务卸载到C / C ++),这对多语言开发人员来说是一个加分项。 Python用途广泛的另一个原因是大型企业(包括FAANG)以及无数小型企业对其的大量使用。如今,Python包里几乎包含了可以想到的任何东西——用于科学计算的Numpy,用于机器学习的Sklearn和用于计算机视觉的Caer。 Python也有缺点 它运行很慢,非常慢 显而易见,在未来很长一段时间里,速度都是开发人员的主要关注点之一。 Python之所以
  • Elixir 和 Julia 之类的语言在什么意义上是同音的?(In what sense are languages like Elixir and Julia homoiconic?)
    问题 Lisp 中的同质性很容易看出: (+ 1 2) 既是以1 、 2作为参数对+的函数调用,也是包含+ 、 1和2的列表。 它同时是代码和数据。 但是,在像 Julia 这样的语言中: 1 + 2 我知道我们可以在 Julia 中将其解析为Expr : :(1 + 2) 然后我们可以获取 AST 并对其进行操作: julia> Meta.show_sexpr(:(1+2)) (:call, :+, 1, 2) 因此,我们可以在 Julia(和 Elixir)中操作程序的 AST。 但是它们是否与 Lisp 具有相同的意义——任何代码片段真的只是语言本身的数据结构吗? 我看不出 Julia 中的1 + 2类的代码是如何立即成为数据的,而 Lisp 中的(+ 1 2)只是一个列表。 那它还是谐音吗? 回答1 用比尔克林顿的话来说,“这取决于‘是’这个词的含义是什么”。 好吧,不是真的,但这确实取决于“homoiconic”一词的含义。 这个词有足够的争议,我们不再说 Julia 是 homoiconic——所以你可以自己决定它是否符合条件。 我将引用 Kent Pitman(对 Lisp 略知一二)在 2001 年的 Slashdot 采访中所说的话,而不是试图定义同质性: 我喜欢 Lisp 愿意代表自己。 人们经常将其解释为它代表自己的能力,但我认为这是错误的。
  • 如何在 REPL 中打印 Julia 中的函数代码?(How to print in REPL the code of functions in Julia?)
    问题 在 Julia 中,很多 Base 和更密切相关的函数也是用纯 Julia 编写的,代码很容易获得。 可以浏览存储库或本地下载的文件,并查看函数是如何编写/实现的。 但我认为已经有一些内置方法可以为您做到这一点,因此您可以在 REPL 或 Jupyter Notebook 中编写如下内容: @code functioninquestion() 并得到类似的东西: functioninquestion(input::Type) some calculations return end而不通过代码分页。 我只是不记得方法或调用。 我已经阅读了手册的反思/内省部分,但我似乎无法在那里使用任何东西。 我已经尝试了methods 、 methodswith 、 code_lowered 、 expand并且似乎无法让它们提供我想要的 - 回答1 虽然这可能不是 OP 想要的,但@less非常方便阅读底层代码(所以我经常使用它)。 例如, julia> @less 1 + 2 给 +(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y))) 这对应于由给出的线 julia> @which 1 + 2 +(x::Int64, y::Int64) at int.jl:8 回答2 目前尚不支持此功能,但将来可能会支持。 回答3
  • 编辑后,如何在活动的Julia会话中重新加载模块?(How do I reload a module in an active Julia session after an edit?)
    问题 2018年更新:请务必检查所有答复,因为多年来对该问题的答案已多次更改。 在此更新时, Revise.jl答案可能是最好的解决方案。 我有一个文件“ /SomeAbsolutePath/ctbTestModule.jl”,其内容为: module ctbTestModule export f1 f1(x) = x + 1 end 我在运行“〜/ .juliarc.jl”的终端中启动了Julia。 启动代码包括以下行: push!(LOAD_PATH, "/SomeAbsolutePath/") 因此,我可以立即输入Julia控制台: using ctbTestModule 加载我的模块。 如预期的那样, f1(1)返回2 。 现在我突然决定要编辑f1 。 我在编辑器中打开“ /SomeAbsolutePath/ctbTestModule.jl”,并将内容更改为: module ctbTestModule export f1 f1(x) = x + 2 end 现在,我尝试在活动的Julia会话中重新加载模块。 我尝试 using ctbTestModule 但是f1(1)仍然返回2 。 接下来,我尝试: reload("ctbTestModule") 如此处建议的,但f1(1)仍返回2 。 最后,我尝试: include("/SomeAbsolutePath
  • 如何在 Julia 中制作 GUI?(How to make a GUI in Julia?)
    问题 我是 Julia 编程的新手,我需要创建一个 GUI。 我一直在寻找信息,但找不到任何有用的信息。 我试图在Julia官方网页中搜索信息,但它似乎已关闭。 我想知道你们有没有人知道我在哪里可以找到有关它的信息。 回答1 这是一个相当笼统的问题,但我会尝试布置环境,以便您可以根据自己的需要做出明智的决定。 如果您在 [Jupyter/IJulia] 笔记本中开发代码,并且需要非常简单的交互,例如滑块更改某些输入值,则 Interact 包是最容易上手的方法。 要开发成熟的 Web UI,请查看 Escher。 受 Elm 的启发,它提供了一个功能性的 UI 组件库。 交互式 Web UI 是在 100% Julia 中创建的。 客户端和服务器端之间的代码没有区别。 该框架处理所有这些。 另一个值得关注的 Web 框架是 Genie,它基于传统的 MVC 设计模式。 它还包括一个 ORM。 Stipple 是一个反应式 UI 库,用于在纯 Julia 中构建交互式数据应用程序。 它使用 Genie.jl(在服务器端)和 Vue.js(在客户端)。 Dash 将下拉菜单、滑块和图形等现代 UI 元素直接与您的 Julia 分析代码联系起来。 以上所有解决方案都是用于创建可通过浏览器访问的 Web 用户界面。 如果您想创建跨平台桌面应用程序,但想使用网络技术(即 HTML/CSS
  • 运行 Julia .jl 文件(Running Julia .jl files)
    问题 我是 julia 的新手,刚刚完成了我的第一个程序。 我在 julia-studio 中编写了代码,并一直在该程序中对其进行测试。 它给了我所有正确的输出,但外壳将输出分开,就好像它是两个不同的执行一样。 我想知道我的编译器是否有问题,所以我想我会尝试在 julialang.org 上找到的默认 julia shell 中编译它。 但是,我无法理解和/或弄清楚如何在那里运行它。 我当前的程序从同一目录中的另一个文件读取输入并输出结果。 任何人都可以解释如何运行该程序。 这个 http://julia.readthedocs.org/en/latest/manual/getting-started/ 对我来说没有意义。 示例输出: julia> program # # # # julia> # # # # # # 代表整数。 理想情况下,输出不应由“julia>”分隔 回答1 如果您想从命令行运行 julia 脚本,那么只需执行 /path/to/julia script-name.jl 在您选择的外壳中。 如果你想从 julia repl 运行它,那么你需要这样的东西: julia> include("path/to/script-name.jl") 至于为什么您的输出如此拆分,我认为我们需要查看您的代码。 回答2 您可以修改脚本并将 julia 二进制文件的路径放在 to