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
rewrite_strat is exponentially slow, takes lots of RAM, and stack overflows (fiat-crypto example) #13708
Comments
cc @ppedrot |
I had a look already at that example, and most of the time is passed in typeclass resolution. To be more precise, the slowdown can be attributed to this line in Class_tactics:
Despite a cache, this keeps recomputing evars appearing in the list of hypotheses of the |
@ppedrot Are you sure? I buy that for In any case, this should not be a bottleneck in these examples because I've set up the typeclass instances so that in fact resolution never backtracks (and should also not exceed a depth of 2 or 3). Can you make let tclLAZY_CONDITIONAL_PLUS (cond : unit -> bool) (tac : tactic) =
match <split successes of tactic> with
| nil -> nil
| success :: rest -> plus success (fun exn -> if cond () then rest exn else tclZERO exn) |
Actually, hm, maybe what you're saying checks out. On the example of size 5, it takes about 10 minutes before the code even gets to typeclass search, but then there's about a half-second pause between the success of one TC problem and the "looking for" of the next one in a log filled with entries like
|
Btw, when looking for |
Jason, how much memory is being used for your test cases? I.e., after a GC compaction and before Qed. If memory use is an issue, perhaps it'sthe same issue seen for setoid_rewrite.
How would that produce exponential behavior? I'm interested in helping to fix the various performance problems affecting large automated proofs. @ppedrot perhaps you would suggest some things for me to look at that would benefit from more tooling/custom analysis routines. I'm also game to try and figure out possible fixes (e.g. the evar issues in #13576 and #13577). Of course, I'm a beginner on this part of the code, indeed I don't even know where to find the important algorithms in the source. Also, perhaps it would be helpful to add tactics or commands to display additional performance-related info, such as the number of evars, their total memory use, the total number of evars that are backtracked, the average number of hypotheses in local context, the number of calls/time spent in a few critical algorithms, etc. which might give Jason or others quicker insight into the cause of performance issues. |
Originally posted by @JasonGross in #13576 (comment)
Btw,
rewrite_strat
is significantly better: You can see some numbers at https://github.com/coq-community/coq-performance-tests/blob/aedb0bab5042af75c65a425d8c9584fd01f8c64e/src/fiat_crypto_via_setoid_rewrite_standalone.v#L652-L662 However, the performance is still exponential, and my estimate is that 5 limbs would take 11-12 hours if it didn't stack overflow after 8, 6 limbs would take 10--11 days, 7 would will take 31--32 weeks, 8 limbs would take 13--14 years, 9 limbs would take 2--3 centuries, 10 limbs would take 6--7 millennia, and 15 limbs would take 2--3 times the age of the universe. (The number of limbs is the argument passed togoal_of_size
.) Note also that 4 limbs takes around 10 GB, and 5 limbs took around 17 GB before stack overflowing.For reference, the numbers here are:
rewrite_strat
(The exponential fit here is only e2 * (# limbs); the estimates above come from fitting the time of the fastest-growing subcall to
rewrite_strat
which grows as roughly e3 * (# limbs)I'd be interested in knowing the performance bottlenecks here, too.
The text was updated successfully, but these errors were encountered: