Dmitry and Joe,

On Mon, Feb 16, 2015 at 1:59 AM, Dmitry Stogov <dmi...@zend.com> wrote:
>
>
> On Mon, Feb 16, 2015 at 12:45 AM, Anthony Ferrara <ircmax...@gmail.com>
> wrote:
>> Well, if you know the destination function at compile time, you don't
>> need to generate generic code. you can generate a direct dispatch
>> (asm-level function call).
>
>
> Right, but in real life app you almost never know what function or method
> you are really call. At function you also can't be sure that it always
> called with proper arguments. This work well only for plain function placed
> into a single PHP file.

I'm not talking about compiling an entire real-life application. I'm
talking about compiling hot-corners. For an application like WP, that
may not be possible. But with some light refactoring it may definitely
be possible with a large portion of applications.

The reason I'm talking about that instead of a generic compiler is
that the simpler the intermediary form (the more we can assume and
throw away) the more aggressive the optimizations can become. In the
long run, I can see a highly optimizing AOT compiler living along side
of a local/tracing JIT compiler. The JIT would handle more dynamic
code.

>>
>>   In this case, strict lets you push type
>> checks back to compile time, where in non-strict mode you still need
>> to generation runtime conversion logic. That runtime conversion logic
>> then requires the ability to hook into Zend's error handling
>> mechanism, vastly complicating the generated code (and the generating
>> code).
>
>
> For cases when you know the called function and all passed and expected
> types, it's possible to use more efficient calling convention passing real
> arguments in CPU registers.
>
> 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.

>>
>>
>> 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.

> 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.

>>
>>
>> > 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.

> Why do you need to generate conversion logic, why can't you call
> Zend API functions ?

We definitely can. However there are 2 problems with that. First the
compiler must know and use the ZVAL abstraction (including the
possibility of type change). The second is that we need to support the
error mechanisms and the generated code needs to be aware of the
engine state (for example, to implement try/catch, etc). Definitely
possible, but also greatly increases complexity... Strict typing makes
those cases compile-time errors, and therefore we don't need to handle
it at all in the generated code.

Thanks

Anthony

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

Reply via email to