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

ext/gmp: Improve parsing of parameters #16685

Merged
merged 22 commits into from
Nov 27, 2024
Merged

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Nov 3, 2024

This PR should be reviewed commit by commit to actually understand what is going on.

The basic idea is to create, and use, a custom Fast ZPP specifier to parse arguments into an mpz_ptr structure. To prevent issues with cleaning up, and improve efficiency as recommended by the GMP documentation, we create some module global mpz_ptr that we initialize and clean once that we can use during ZPP, without needing to worry about clean-up.

This new model greatly simplifies the extension and how to handle parameters, as they will always be mpz_ptr structures.

The first couple of commits are some fixes and preliminary refactorings, the main one being to convert all relevant calls to Fast ZPP.

I have not benchmarked this, but I would not be surprised if this improves performance of the extension.

This should allow some easier refactoring of the operator overloading handlers to behave more sensibly and not just throw Errors all the time.

@@ -26,7 +26,7 @@ try {
echo "Done\n";
?>
--EXPECT--
int(2)
int(1)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe instead something like this $res = gmp_cmp(123123,-123123); <if 64 bits expects 1 or die>... wdyt ?

@@ -26,7 +26,7 @@ try {
echo "Done\n";
?>
--EXPECT--
int(2)
Copy link
Member

Choose a reason for hiding this comment

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

This seems to cause a test failure on some CI jobs, so something more is going on

Copy link
Member Author

Choose a reason for hiding this comment

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

The documentation of GMP says:

Compare op1 and op2. Return a positive value if op1 > op2, zero if op1 = op2, or a negative value if op1 < op2.

So probably we shouldn't be using the output of the values directly?

Copy link
Member

Choose a reason for hiding this comment

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

Oh I see, reading source codes, seems mpir and gmp differ with mpz_gmp. The former can return the values -1, >= 0, GMP it is only -1, 0, 1 (if this is what you meant by "normalization" in your gmp_cmp commit).

Copy link
Member

Choose a reason for hiding this comment

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

Good find! I guess PHP should normalize such that the two libs have the same behaviour

ext/gmp/gmp.c Show resolved Hide resolved
ext/gmp/gmp.c Show resolved Hide resolved
ext/gmp/gmp.c Outdated Show resolved Hide resolved
ext/gmp/gmp.c Show resolved Hide resolved
ext/gmp/gmp.c Show resolved Hide resolved
ext/gmp/gmp.c Outdated Show resolved Hide resolved
@Girgias Girgias force-pushed the gmp-zpp-custom branch 2 times, most recently from d4dff8a to dff6bc0 Compare November 3, 2024 13:43
@Girgias Girgias requested a review from nielsdos November 10, 2024 20:35
Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

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

I did some small benchmarks tests and found that performance is indeed better, and it's even cleaner code, really nice work.

ext/gmp/gmp.c Outdated
}
return FAILURE;
}
if (!gmp_zend_parse_arg_into_mpz_ex(op2, &gmp_op2, 1, true)) {
Copy link
Member

Choose a reason for hiding this comment

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

You pass arg_num==1 here, is that right? shouldn't it be 2?

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 should yes

typedef void (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, gmp_ulong);
typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
typedef gmp_ulong (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, gmp_ulong);
if (!ZEND_ARG_USES_STRICT_TYPES()) {
Copy link
Member

Choose a reason for hiding this comment

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

So strict types only apply on function call arguments right and operators operands should always coerce IIRC. But this code doesn't do that or what am I missing? I think there was a discussion about this at one point.

@Girgias Girgias merged commit 0800c68 into php:master Nov 27, 2024
9 of 10 checks passed
@Girgias Girgias deleted the gmp-zpp-custom branch November 27, 2024 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants