On Mon, Feb 16, 2015 at 5:21 PM, Anthony Ferrara <ircmax...@gmail.com>
wrote:

> Dmitry,
>
> On Mon, Feb 16, 2015 at 9:12 AM, Dmitry Stogov <dmi...@zend.com> wrote:
> >
> >> > The type checks in PHP7 is quite cheap (2-3 CPU instructions). Strict
> or
> >> > weak check doesn't make any difference for "fast path" (the same 2-3
> >> > instructions). The slow patch for weak checks is going to be a bit
> more
> >> > expensive.
> >>
> >> Well, not really. It's 2-3 CPU instructions once you have the
> >> instructions for dealing with ZVALs. The concept I'm talking is having
> >> the AOT compiler not know anything about a ZVAL (except perhaps at an
> >> FFI level). So yes, it's 2-3 CPU instructions to check type, but it's
> >> also a branch. It's also more memory and values to keep track of. It's
> >> far more code to generate.
> >
> >
> >
> > This is code for week type check:
> >
> >     cmpb  Z_TYPE_P(%edx), IS_LONG
> >     je     slow_path
> > L1:
> >     addl  Z_LVAL_P(%edx), %eax
> >
> > ....
> >
> > slow_path:
> >     movl %edx, (%esp)
> >     call convert_to_long
> >     jmp L1
> >
> > This is code for strict type check:
> >
> >     cmpb  Z_TYPE_P(%edx), IS_LONG
> >     je     slow_path
> > L1:
> >     addl  Z_LVAL_P(%edx), %eax
> >
> > ....
> >
> > slow_path:
> >     movl %edx, (%esp)
> >     ...
> >     call zend_error
> >     jmp L1 ; we still have to support E_RECOVERABLE, so we may return
> back
> >
> > No big difference...
>
> The code I'm talking about generating is:
>
> addl %edx %eax
>
> No jumps, no type extraction, because it happened at compile time (and
> strict lets us do that since we can determine types 100% at compile
> time since dynamic types become errors).


> So it's a significant difference (1 less conditional jump, 1 less
> unconditional jump, 1 less comparison, a number less operations, etc).
>

If we know the type at compile-time we don't check it as well.
If you don't know it at compile-time you have to check it at run-time to
catch the error.


> >>
> >>
> >> >>
> >> >>
> >> >> In fact, the research I have been doing is precisely around that
> >> >> (where I know for a fact that all remaining function calls are going
> >> >> to be typed, and compile the entire block at one time with direct
> >> >> calls). So that way I never need to actually do even as much as a FCC
> >> >> to call a userland function. Which then lets me avoid generating
> >> >> typing code (since I know the types). Which is why I'm advocating for
> >> >> strict, since that way we can treat an entire graph of function calls
> >> >> as strict and compile them all in one go (no need to even JIT at
> >> >> runtime, just compile AOT).
> >> >>
> >> >> If your research has shown something different, care to share?
> >> >
> >> >
> >> > Very similar :), but in cases when we know the called function the
> >> > effect
> >> > from type hinting is negligible. It's almost always possible to
> generate
> >> > optimal code without any hints.
> >>
> >> It's always possible to generate optimal PHP code. But I want to
> >> generate optimal ASM code. And for that, I need type guarantees.
> >
> >
> > Doesn't week type hint make the same guarantee as strong?
> > It just makes conversion on mismatch.
>
> No, because I still need to promote back up to ZVAL before calling
> another function (since the type conversion is allowed). Therefore I
> cant error on type conversion, I need to generate the code to handle
> it.
>

I see the difference now, but your approach won't work for all cases (like
call through zend_call_user_func).
It should be explained again by a bit different goals.

Thanks. Dmitry.


>
> >>
> >>
> >> > See code for fibo_r() from bench.php generated by our old JIT for
> >> > PHP-5.5
> >> > (without type hinting):
> >> > https://gist.github.com/dstogov/5f71d23f387332e9d77c
> >> >
> >> > Unfortunately, we didn't make the same for PHP7 yet.
> >> > More important, in our experiments we saw improvements only on small
> >> > benchmarks (e.g. 25 times on mandelbrot), but nothing on real-life
> apps.
> >> >
> >> > So a some point, looking into ASM code that endlessly allocates and
> >> > frees
> >> > zvals, we switched to engine re-factoring.
> >>
> >> Which for generic code, is amazing. And I'm all for optimizing dynamic
> >> code. You're going to get an overall big gain doing that. I just see a
> >> bigger gain is possible given some preconditions, and would love to
> >> see them working together.
> >
> >
> > I'm looking forward as well :)
> > Just busy with other things now.
> >
> >>
> >>
> >> >>
> >> >>
> >> >> > According to mandel() and integer to float conversion in the loop,
> >> >> > it's
> >> >> > possible to perform a backward data-propagation pass to catch this
> >> >> > case
> >> >> > and
> >> >> > replace integer by float in first place. We did it in our old JIT
> >> >> > prototypes
> >> >> > without any type hinting. Also, don't use "fild", use SSE2 and/or
> >> >> > AVX.
> >> >>
> >> >> I did wind up doing a few passes to back-propagate the cast (among
> >> >> other optimizations). But it's still a point that the conversions
> >> >> aren't exactly cheap. But as I said before, that was a side-note and
> >> >> not really an argument for/against strict typing. So worth
> mentioning,
> >> >> but shouldn't affect anyone's decision.
> >> >>
> >> >> Re fild vs SSE/AVX: that was up to the backend code generator we were
> >> >> using (libjit). It may be an open req against that lib to generate
> the
> >> >> different instruction, or perhaps it just failed a heuristic. We were
> >> >> working a level higher than the generated ASM, so not really 100%
> sure
> >> >> why it made that decision.
> >> >
> >> >
> >> > I saw a big speed difference between FPU and SSE2/AVX code on
> bench.php,
> >> > so
> >> > if you may tell libjit to use SSE2/AVX - do it.
> >>
> >> Yeah, I'm not sure it's worth it at this stage, but will definitely
> >> keep in mind.
> >>
> >> > Right, but it's not always possible to know the types at compile time,
> >> > and in this case hints may be helpful, however, strict and week hints
> >> > give
> >> > exactly the same information - they guarantee the type of argument
> >> > inside
> >> > the function.
> >>
> >> Well, yes. However it also means that inside the function dynamic
> >> types (variables that change type) are fine, and you need to implement
> >> the conversion logic. Therefore you need to implement ZVAL
> >> abstractions in the compiler. Something I really want to avoid, as it
> >> exponentially raises the complexity that you need to handle.
> >
> >
> > We had different goals and may misunderstand each other.
> > We tried to make 100% transparent JIT for PHP that would able to run any
> > code.
>
> I think the high-level goals are the same, but yes, the low level
> goals are very different. I see we compliment each other rather than
> oppose. Which is why I am excited by it :-).
>
> Thanks for the discussion :-)
>
> Anthony
>

Reply via email to