Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mpfr: speed improvements #27331

Merged
merged 2 commits into from
Jun 12, 2018
Merged

mpfr: speed improvements #27331

merged 2 commits into from
Jun 12, 2018

Conversation

vtjnash
Copy link
Member

@vtjnash vtjnash commented May 30, 2018

Unlike GMP / BigInt, the MPFR / BigFloat library exposes an interface for external allocation:
http://www.mpfr.org/mpfr-current/mpfr.html#Custom-Interface

Using that allows us to use our fast memory-pool gc, and avoid adding finalizers and use the slow malloc/free functions, and allows us to better track memory pressure.

function benchwork(x, y)
    for i in 1:100000000
          x += y
     end
     return x
end
@time benchwork(big"0.0", big"23.0")
 12.923691 seconds (200.00 M allocations: 8.196 GiB, 31.56% gc time)
  5.469907 seconds (200.00 M allocations: 10.431 GiB, 6.15% gc time)

(@profile now indicates that this is now about equal parts mpfr time and allocation-related time)

@StefanKarpinski
Copy link
Member

Does this help with serializing and deserializing BigFloats?

Keno
Keno previously requested changes May 31, 2018
@@ -55,18 +56,29 @@ mutable struct BigFloat <: AbstractFloat
sign::Cint
exp::Clong
d::Ptr{Limb}
# _d::Buffer{Limb} # Julia gc handle for memory @ d
_d::String # Julia gc handle for memory @ d (optimized)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating immutable memory is dangerous. If you must have this add a FixedSizeBuffer type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not that dangerous, it's only bad if this pointer gets leaked anywhere else, but it's purely internal. I mean, it's not like there's a deepcopy method definition here that assumes they can't be mutated or anything like that. No, that would be crazy talk, and definitely not a bug in this very PR. :P

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, is it a problem though? since BigFloat itself is not supposed to be mutated either, they share the same danger if someone violated that expectation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immutable memory is still being overwritten (since you construct it and then overwrite it with the result of an operation). I agree that it's much less likely to be harmful, since the compiler shouldn't be able to know the objectid of a newly-allocated bigfloat that gets subsequently modified (as long as the BigFloat itself isn't mutated more than once), but it does sound fairly risky.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that just the same concern as any other usage of String?

vtjnash added 2 commits June 11, 2018 16:35
This would have caused us to perform a number of unncessary allocations and method specializations
Unlike GMP / BigInt, the MPFR library exposes an interface for external allocation:
http://www.mpfr.org/mpfr-current/mpfr.html#Custom-Interface

Using that allows us to use our fast memory-pool gc
and avoid adding finalizers and use the slow malloc/free functions.
(and in some cases, some of it might even end up on the stack!)

Also switch to allocating lgamma_sign on the stack, for better performance (and thread-safety)

Also fixes Serialization to preserve BigFloat precision.
@vtjnash
Copy link
Member Author

vtjnash commented Jun 11, 2018

Does this help with serializing and deserializing BigFloats?

Forgot to add that to the initial commit – now it does :)

@vtjnash vtjnash dismissed Keno’s stale review June 11, 2018 22:27

Keno agreed this should be no worse than the current existence of _string_n in other code.

@KristofferC
Copy link
Member

@nanosoldier runbenchmarks("scalar", vs = ":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan

@KristofferC
Copy link
Member

Nice :)

@vtjnash
Copy link
Member Author

vtjnash commented Jun 12, 2018

So, about 25% faster. (The allocation difference is just previous measurement error)

@Sacha0
Copy link
Member

Sacha0 commented Jun 12, 2018

Nice :)

An understatement! That's fantastic! 🎉

@vtjnash vtjnash merged commit 82ae7f3 into master Jun 12, 2018
@vtjnash vtjnash deleted the jn/mpfr-perf branch June 12, 2018 19:29
@KristofferC
Copy link
Member

It was lucky that it had memory regressions or we wouldn't have seen the speed improvements because the threshold is put to 50% (e.g. needs to become twice as fast for it to be considered insignificant). Feels kinda high...

@dlfivefifty
Copy link
Contributor

FYI this PR is probably the cause of a SEGFAULT in gamma(big(0)) :

JuliaMath/SpecialFunctions.jl#101 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bignums BigInt and BigFloat performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants