Precompilation or sysimg building not working as expected


#1

Our company has a medium size Julia app that we run from the command line. Because every time we run we start a new julia instance we have a good amount of overheard in loading the libraries we use and priming the JIT compiler.

Our app starts with essentially one function call. If I just call this function twice during the same run of julia the first call takes around 20 seconds and the second takes 0.1 seconds. What I want is for the first call to take the same amount of time as the second call, is this an achievable goal?

I tried using the precompile statement, which gave me some speedup, but not what I wanted. (The 20 seconds quoted above is actually with precompile statement enabled)

I also tried building a new system image with the included script. This works much better, reducing the time down to 1.6 seconds.

Is there any way to get the first run all the way down to the second run time of 0.1, or is that just asking too much?


#2

When you say you’re using the precompile statement, do you mean the __precompile__() at the top of your module, or are you explicitly calling precompile(myfunction, (MyInputType, MyOtherInputType))?


#3

__precompile__() at the top of my module.


#4

I’d suggest trying the second form. For example:

precompile(min, (Int, Int))

SnoopCompile can also help you figure out exactly which precompile() calls you’ll need. But the first thing to try would just be whatever your 20-second function is.


#5

By the way, the reason this is necessary is that, as I understand it, __precompile__() can’t generally know what input types to compile your functions for, since that would require knowing exactly what input types the user might supply to your functions (which it can’t possibly know ahead of time). But if you do know, then you can supply those input types when you call precompile(...).


#6

I will try with the function, but in the module where we call __precompile__() we also exercise our app with real world inputs in an attempt to prime the JIT compiler, which I think serves the same purpose as calling the function with arguments.


#7

Assuming you mean contrib/build_sysimg.jl, did you specify a custom userimg file?

Alternatively, try putting your precompile calls in base/userimg.jl and rebuild through the usual process (make, no need to run build_sysimg).

The build_sysimg code and output look ok on OS X, but isn’t part of the standard build process and I don’t think it’s really tested. So there might be some subtleties missing on some platforms.

A no-op run (time julia -e "") on my system is close to .25s, so you might not be able to get a first run down to 0.1s.


#8

I did specify a customer userimg file, it is just one line: using $MyModule

The function form did not significantly speed up the operation. It is looking like 1.6 seconds is the best I can hope for now. (Much better than the original 20 seconds!)


#9

@jminardi out of curiosity, what was the change that got you down from 20s to 1.6s?


#10

I build a sysimg with my module included. See here:

http://docs.julialang.org/en/stable/devdocs/sysimg/