Why these 2 functions generate very different llvm?

203 views
Skip to first unread message

FANG Colin

unread,
May 30, 2016, 7:11:47 PM5/30/16
to julia-users

function t1(n::Int, x::Int, a::Float64)
   x::
Float64 = x
   
for i in 1:n
        x 
+= a
   
end
    x
end
@time t1(
10^6, 1, 1.0)

0.005445 seconds (1.00 M allocations: 15.259 MB)




function t2(n::Int, y::Int, a::Float64)
   x::
Float64 = y
   
for i in 1:n
        x 
+= a
   
end
    x
end
@time t2(
10^6, 1, 1.0)

0.001044 seconds (6 allocations: 192 bytes)




The @code_warntype of the 2 functions are very similar. However, the llvm code generated from t2 is a lot simpler.


Does it suggest that if we want to change the type of an argument, we'd better create a new variable?

David P. Sanders

unread,
May 30, 2016, 7:23:10 PM5/30/16
to julia-users


El lunes, 30 de mayo de 2016, 19:11:47 (UTC-4), FANG Colin escribió:

function t1(n::Int, x::Int, a::Float64)
   x::
Float64 = x
   
for i in 1:n
        x 
+= a
   
end
    x
end
@time t1(
10^6, 1, 1.0)

0.005445 seconds (1.00 M allocations: 15.259 MB)


In t1, x changes type during the function, from Int to Float64, so the function is type *un*stable, as shown by @code_warntype,
and as suggested by the huge number of allocations.

In t2, x is always a Float64, and the function is type stable.
 





function t2(n::Int, y::Int, a::Float64)
   x::
Float64 = y
   
for i in 1:n
        x 
+= a
   
end
    x
end
@time t2(
10^6, 1, 1.0)

0.001044 seconds (6 allocations: 192 bytes)




The @code_warntype of the 2 functions are very similar. However, the llvm code generated from t2 is a lot simpler.


The @code_warntype of the two functions is very *different*. (This is easier to see in the REPL than in the notebook, if
that is the problem.)

Yichao Yu

unread,
May 30, 2016, 7:47:59 PM5/30/16
to Julia Users
This is a known bug. Fortunately it's easy to catch with code_warntype.

Erik Schnetter

unread,
May 30, 2016, 7:54:57 PM5/30/16
to julia...@googlegroups.com
Yichao

What is the known bug here: That Julia doesn't handle this more efficiently, or that the variable `x` can change its type from Int to Float64?

In this example, are there two variables `x` (the argument and the explicitly declared local variable), or should the declaration be an error?

-erik

Yichao Yu

unread,
May 30, 2016, 8:14:21 PM5/30/16
to Julia Users
On Mon, May 30, 2016 at 7:54 PM, Erik Schnetter <schn...@gmail.com> wrote:
> Yichao
>
> What is the known bug here: That Julia doesn't handle this more efficiently,

The bug is that the type instability here is spurious.

Tobias Knopp

unread,
May 31, 2016, 1:11:11 AM5/31/16
to julia-users
It would be great if this is resolvable. It took me quite some time to determine that this is an issue in my own code. My mental model was that type stability is about the return type being statically dependent on the input parameter types. That a local binding has changed is quite a different thing.

Cheers,

Tobias

Stefan Karpinski

unread,
May 31, 2016, 10:14:27 AM5/31/16
to Julia Users
This isn't exactly a bug since the answer is correct, it's an optimization that we don't yet do. (If all of those are bugs then every language implementation has an infinite number of bugs.) But yes, fixing this is on track. There's been a lot of recent work on Julia's IR which should make this problem resolvable soon.

Tobias Knopp

unread,
May 31, 2016, 6:02:09 PM5/31/16
to julia-users
100% agree. I did not wanted to imply that this is a bug but a "surprising slow pass" (at least for me). So absolutely thumbs up if there is an opportunity of optimizing this case!

Cheers,

Tobias
Reply all
Reply to author
Forward
0 new messages