Zeev,

On Sun, Feb 22, 2015 at 1:37 PM, Zeev Suraski <z...@zend.com> wrote:
>> -----Original Message-----
>> From: Jefferson Gonzalez [mailto:jgm...@gmail.com]
>> Sent: Sunday, February 22, 2015 4:25 PM
>> To: Etienne Kneuss; Anthony Ferrara; Zeev Suraski
>> Cc: PHP internals
>> Subject: Re: [PHP-DEV] Coercive Scalar Type Hints RFC
>>
>
> Jefferson,
>
> Please note that Anthony, the lead of the Dual Mode RFC, said this earlier
> on this thread, referring to the claim that Strict STH can improve JIT/AOT
> compilation:
>
> "A statement which I said on the side, and I said should not impact RFC or
> voting in any way. And is in no part in my RFC at all."
>
> Please also see:
>
> marc.info/?l=php-internals&m=142439750614527&w=2
>
> So while Anthony and I don't agree on whether there are performance gains
> to be had from Strict STH, both of us agree that it's not at a level that
> should influence our decision regarding the RFCs on the table.
>
> I wholeheartedly agree with that stance, which is why I also listed the
> apparently extremely widespread misconception (IMHO) that Strict STH can
> meaningfully help JIT/AOT in my RFC.

So you agree we shouldn't discuss it, then you go ahead and discuss
it. I guess that shouldn't surprise me.

> Despite that, as your email suggests, there are still (presumably a lot)
> of people out there that assume that there are, in fact, substantial gains
> to be had from JIT/AOT if we introduce Strict STH.  I'm going to take
> another stab at explaining why that's not the case.
>
>> A JIT or AOT machine code generator IMHO will never have a decent use of
>> system resources without some sort of strong/strict typed rules,
> somebody
>> explain if thats not the case.
>
> It kind of is and kind of isn't.
>
> There's consensus, I think, that if PHP was completely strongly typed -
> i.e., all variables need to be declared and typed ahead of time, cannot
> change types, etc. - we'd clearly be able to create a lot of optimizations
> in AOT that we can't do today.  That the part that 'is the case'.  But
> nobody is suggesting that we do that.  The discussion on the table is
> very, very narrow:

There's no consensus there. As I've pointed out to you more than once,
plenty of other languages manage this through type inference or
reconstruction. Many (like Go) only requiring explicit types on the
parameters, not on variables.

Heck, I did **exactly** that in Recki-CT. So please don't dismiss
something that's being done **IN THE PHP WORLD** just because you
don't think it's possible.

> -- Can the code generated for a strict type hint can somehow be optimized
> significantly better than the code generated for a dynamic/coercive type
> hint.
>
> And here, I (as well as Dmitry, who actually wrote a JIT compiler for PHP)
> claim that it isn't the case.  To be fair, there's no consensus on this
> point.

And me, who wrote an AOT compiler that does **exactly** this, claim
that it is the case. Along with other people who've worked on
compilers. See the reply in a private thread you started that shows
the tradeoffs, specifically in generated code efficiency and memory
usage.

You can keep ignoring the arguments, but PLEASE don't keep spreading
them as "fact".

Also: if Dmitry worked on a JIT compiler, why isn't that code out in
the open? And if the code isn't out, why isn't the knowledge open? Are
we just supposed to rely on a single person's experience (especially
when more than one other person's shared experiences differ)?

> Let me attempt, again, to explain why we don't believe there are any gains
> associated with Strict STH, be them with the regular engine, JIT or AOT.
>
> Consider the following code snippet:
>
> function strict_foo($x)
> {
>   if (!is_int($x)) {
>     trigger_error();
>   }
>    .inner_code.
> }
>
> function very_lax_foo($x)
> {
>     $x = (int) $x;
>    .inner_code.
> }
>
> function test_strict()
> {
>   .outer_code.
>   strict_foo($x);
> }
>
> function test_lax()
> {
>   .outer_code.
>   very_lax_foo($x);
> }
>
> test_strict();
> test_lax();
>
>
> strict_foo() implements a pretty much identical check to the one that a
> Strict integer STH would perform.
> very_lax_foo() implements an explicit type conversion to int, that can
> pretty much never fail - which is significantly more lax than what is
> proposed for weak types in the Dual Mode RFC, and even more so compared to
> the Coercive STH RFC.
> .inner_code. is identical between the two foo() functions, and
> .outer_code. is identical between the two tester functions.
>
> The claim that strict types can be more efficiently optimized than more
> lax types, suggests it should be possible to optimize the code flow for
> test_strict()/strict_foo() significantly better than for very_lax_foo()
> using JIT/AOT.

Assuming that they were split in the files appropriately, you are
missing **THE** key thing we've been trying to tell you this entire
time. Looking at a single function, yes there is no difference if it's
strict or not (well, you can save some time on the next function call
inside, but it's small). However we're not talking about looking at a
single function.

In your code, a compiler could compile test_strict into a "php"
function. Which would (assuming that it accepted arguments) accept a
ZVAL. Then it would do any type assertions necessary. At this point
there's no difference between the approaches.

However, since test_strict() is compiled, there's no reason to
dispatch back up to PHP functions for strict_foo(). In fact, that
would be exceedingly slow. So instead, we'd compile strict_foo() as a
C function, and do a native function call to it. Never having to check
types because they are passed on the C stack.

That's precisely what I'm doing with Recki-CT when generating PECL
extensions from PHP code. It would look like this:

PHP_FUNCTION(test_strict) {
    zend_bool valid_return = 0;
    if (!zend_parse_parameters(...)) {
        return;
    }
    internal_test_strict(&valid_return);
}

void internal_test_strict(zend_bool *valid_return) {
    //outer_code
    zend_bool foo_valid = 0;
    internal_strict_foo(x, &foo_valid);
    if (!foo_valid) {
        throw_error();
    }
}

And then generate the same proxy structure for strict_foo. So there's
no need to ever do type assertions after the first external call (from
weak mode).

So that means there's no need to build up a ZVAL from native code.
There's no reason to type assert it. There's no reason to dispatch a
PHP-level function.

And note that this can only work with strict types since you can do
the necessary type inference and reconstruction (both forward from a
function call, and backwards before it).

With lax (weak, coercive) types, the ability to do type reconstruction
drops significantly. Because you can no longer do any backwards
inference from other function calls. Which means you can't prove if a
type is stable in most cases (won't change). Therefore, you'll always
have to allocate a ZVAL, and then the optimizations I showed above
would stop working.

> To simplify things, let's assume we can know - with absolute confidence,
> that $x is an int right before the call.  Can we somehow optimize
> test_strict()/strict_foo() better than test_lax()/very_lax_foo()?  The
> answer is - no, not really.  We could optimize them down to the exact same
> machine level code - bypassing the is_strict() check in the strict_foo()
> case, and the explicit cast in very_lax_foo() case.  With absolute
> confidence that $x is an int, we could have a single long pass the
> caller-callee boundary in both cases.  This is easier said than done -
> JIT/AOT are quite complex - but it's equally hard in both cases, and the
> end result is identical.

Actually, I just demonstrated how, yes, we can optimize the entire
thing better than test_lax.

>> 1. Does weak mode could provide the required rules to implement a JIT
> with
>> a sane level of memory and CPU usage?
>
> It would use the exact same amount of memory and CPU as strict mode.  The
> hard part remains inferring types - and as I hoped I illustrated, there's
> no different between different flavors of STH in that front.

This was demonstrated to be false both by my code above (in which
calls from compiled code would use significantly less memory due to
not needing zvals at all), and by mails in private that show existing
JIT compilers and their memory overheads (specifically around V8's
engine vs others).

>> 2. I see that the proponents of dual weak/strict modes are offering to
> write a
>> AOT implementation if strict makes it, And the impresive work of Joe
> (JITFU)
>> and Anthony on recki-ct with the strict mode could be taken to another
> level
>> of integration with PHP and performance. IMHO is harder and more
> resource
>> hungry to implement a JIT/AOT using weak mode. With that said, if a JIT
>> implementation is developed will the story of the ZendOptimizer being a
>> commercial solution will be repeated or would this JIT implementation
> would
>> be part of the core?
>
> Actually, what I'm seeing is the proponents of dual weak/strict mode
> saying that JIT/AOT should not be a part of the discussion around the
> RFCs, and people refusing to accept that! :)

You made it part of the conversation by having it in your RFC. You
make it part of the conversation by repeating the "It's our opinion
that..." rhetoric.

It should be removed from your RFC completely (including any reference
to performance or compilation other than of the direct implementation
being provided). It's not in my RFC at all. The fact that it's in
yours does raise some questions.

> But more importantly, as early as when we announced PHPNG, we said we'd
> want to look into JIT solutions once it ships.  We'd obviously want to
> cooperate with everyone interested to try and create the best JIT
> implementation possible once PHP 7 is out the door, as a part of an open
> effort.  If it's ever any good, it'll make it into the core, if accepted.

Do you want to cooperate? Then share the work that was done by Dmitry
already. Keeping bringing it up while refusing to share it is the
exact opposite of cooperation.

Anthony

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to