-
Notifications
You must be signed in to change notification settings - Fork 163
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 method selection in C #2308
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2308 +/- ##
==========================================
+ Coverage 72.33% 72.49% +0.15%
==========================================
Files 479 478 -1
Lines 250960 247780 -3180
==========================================
- Hits 181538 179617 -1921
+ Misses 69422 68163 -1259
|
I'm mostly happy with this. My only concern (as with so much of GAP), is lack of testing (which didn't exist before!) For example, in the tracing we used to print |
Just out of curiosity (and to address the "more C code" objection) how much performance do we lose if we just stop bothering to compile these functions (thereby getting rid of the 5600 lines of C) and then look at compacting the GAP code. If the method cache really is doing all the heavy lifting, then it shouldn't make much difference. That said, the C code is commented and readable and much more concise than the current GAP code, so I'm quite happy with it. |
src/opers.c
Outdated
// | ||
// If <constructor> is non-zero, then <oper> is a constructor, leading | ||
// to <types[0]> being treated differently. | ||
static ALWAYS_INLINE Obj GetMethodUncached_NEW( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment to explain the point of the ALWAYS_INLINE and that you expect it to be called with
some of the parameters compile-time constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
@ChrisJefferson regarding testing, I actually started to add testing for a lot of these things in PR #2296, including (old-style) profiling and tracing -- admittedly for both only tiny infant versions, but it's a start, and I hope more can and will be added. As to "Trying next" being lost" oops, that's indeed a mistake, I did not notice |
@stevelinton what do you mean by "compacting the GAP code? One thing would be to merge Finally, one could try to merge the different arity methods together, but that sounds more complicated, so perhaps I'd stop before that. I can look into doing that, I guess. Well, the first step would be to check how much of an impact it has to not compile |
@fingolfin, I was thinking fairly generally along those lines. If we believe that code is not performance critical, then we can dramatically reduce the repetition. I agree about the first experiment to try. |
Quick test, with methsel1.g compiled:
With it not compiled:
Repeating this several times gives fairly consistent results. So not compiling this code slows down startup noticeably. On the other hand, that may be due to the method cache not yet being "warmed up". Running tst/testinstall.g shows less of a difference, but still: with compiled code it's about 75 seconds, without it about 80 seconds. |
Just one comment with regards |
Updated to (hopefully) address all comments by @ChrisJefferson and @stevelinton |
@fingolfin that's more than enough evidence for me to justify replacing 1500 lines of GAP with 100 lines of C. |
We have plenty of other examples of kernel functions FOOBAR without argument validation, coupled with a library visible function with the same name that does perform argument validation. No reason to treat this case special by adding an "Unchecked" prefix.
This is mostly about simplifying the code, and reducing code duplication, and less about performance (there seems to be a negligible difference with that). In this first commit, the new method lookup code is added, but does not replace the old code; instead, the results of the new and old code are compared. This successfully passes the testinstall test suite, giving confidence that the new code is correct.
@ChrisJefferson @stevelinton any other remarks? otherwise, can we merge this? |
This is not about performance (the difference seems to be negligible; the method cache is doing a darn good job, it seems). Instead, the main motivation for this is simplification and reduction of code duplication: less than 100 lines of documented C code replace > 1500 lines of GAP code, as well as > 5600 lines of C code generated from that GAP code.
To verify that the new code is correct, I used it in parallel to the old code, adding in a check to verify that old and new method lookup code agree (the commit with this state is in this PR, so one can easily reproduce this). This passed the
testinstall
test suite (after revealing lots of bugs in my initial code, that is ;-).The main drawback of this effort is that yet a bit more of low-level GAP code is replaced by GAP code, which might annoy people like @markuspf who are interested in reimplementing the GAP kernel in languages other than C. However, I think this PR actually does not add much to the burden, as the new C function still is pretty straight forward to rewrite in other languages, which one has to do with the rest of the method selection code anyway.