Something in Dmitry's attribute RFC caught my attention. There is an
example implying inline functions indicated by an attribute.
I know that was only a potential use case for an extension. But it made me
wonder how much that could improve PHPs performance if we actually had it.
As I understand it, the process by which the call stack is updated and
scope changed, is quite expensive. And from tests I can see that function
calls do actually add a not insignificant overhead to intensive repetitive
tasks.
So how difficult would it be to get the engine to determine if an inline is
feasible, then skip the fcall init, and dump the a functions opcode emits
directly into the current scope?
On Thu, Apr 28, 2016 at 1:21 AM, Dominic Grostate
codekestrel@googlemail.com wrote:
As I understand it, the process by which the call stack is updated and
scope changed, is quite expensive. And from tests I can see that function
calls do actually add a not insignificant overhead to intensive repetitive
tasks.So how difficult would it be to get the engine to determine if an inline is
feasible, then skip the fcall init, and dump the a functions opcode emits
directly into the current scope?
I'm actually working on a proof-of-concept of that already. I've
already got basic proxy methods getting inlined, and am working up
through expression methods and trying to resolve scoping with $this
and non-publics.
I'll publish a branch on github when I have something interesting to share.
-Sara
That sounds wicked. I look forward to benchmarking it and seeing how its
done.
On Thu, Apr 28, 2016 at 1:21 AM, Dominic Grostate
codekestrel@googlemail.com wrote:As I understand it, the process by which the call stack is updated and
scope changed, is quite expensive. And from tests I can see that
function
calls do actually add a not insignificant overhead to intensive
repetitive
tasks.So how difficult would it be to get the engine to determine if an inline
is
feasible, then skip the fcall init, and dump the a functions opcode emits
directly into the current scope?I'm actually working on a proof-of-concept of that already. I've
already got basic proxy methods getting inlined, and am working up
through expression methods and trying to resolve scoping with $this
and non-publics.I'll publish a branch on github when I have something interesting to share.
-Sara
On Thu, Apr 28, 2016 at 8:39 PM, Dominic Grostate <
codekestrel@googlemail.com> wrote:
That sounds wicked. I look forward to benchmarking it and seeing how its
done.On Thu, Apr 28, 2016 at 1:21 AM, Dominic Grostate
codekestrel@googlemail.com wrote:As I understand it, the process by which the call stack is updated and
scope changed, is quite expensive. And from tests I can see that
function
calls do actually add a not insignificant overhead to intensive
repetitive
tasks.So how difficult would it be to get the engine to determine if an
inline
is
feasible, then skip the fcall init, and dump the a functions opcode
emits
directly into the current scope?I'm actually working on a proof-of-concept of that already. I've
already got basic proxy methods getting inlined, and am working up
through expression methods and trying to resolve scoping with $this
and non-publics.I'll publish a branch on github when I have something interesting to
share.-Sara
I also have a proof-of-concept inlining implementation lying around:
https://github.com/nikic/php-src/blob/opt/ext/opcache/Optimizer/inlining.c
However it only inlines free functions and static methods, not instance
methods, because the latter have the $this being null issue. Another
complication when inlining methods is that we may only know the called
method if it is either private or final, i.e. there is no possibility of it
being overwritten in a child class.
One tricky issue with inlining is that we need to unset all the variables
of the inlined function after the call, otherwise we may cause issues with
references and destruction order. If these unsets are not eliminated
through DCE they may be pretty expensive (for a larger number of vars).
Furthermore inlining increases the number of variables in the function
(which need to be initialized and destroyed), which may be problematic when
inlining into unlikely branches. (Register allocation for CVs would improve
this).
Nikita
I figured class methods would be a problem, especially if it were
implemented at compile time as the compiler wouldn't necessarily know which
class it refers to.
Curious though, which part of the function call causes the performance hit?
I've noticed that the number of parameters it has contributes a large part
it.
On Thu, Apr 28, 2016 at 8:39 PM, Dominic Grostate <
codekestrel@googlemail.com> wrote:That sounds wicked. I look forward to benchmarking it and seeing how its
done.On Thu, Apr 28, 2016 at 1:21 AM, Dominic Grostate
codekestrel@googlemail.com wrote:As I understand it, the process by which the call stack is updated and
scope changed, is quite expensive. And from tests I can see that
function
calls do actually add a not insignificant overhead to intensive
repetitive
tasks.So how difficult would it be to get the engine to determine if an
inline
is
feasible, then skip the fcall init, and dump the a functions opcode
emits
directly into the current scope?I'm actually working on a proof-of-concept of that already. I've
already got basic proxy methods getting inlined, and am working up
through expression methods and trying to resolve scoping with $this
and non-publics.I'll publish a branch on github when I have something interesting to
share.-Sara
I also have a proof-of-concept inlining implementation lying around:
https://github.com/nikic/php-src/blob/opt/ext/opcache/Optimizer/inlining.cHowever it only inlines free functions and static methods, not instance
methods, because the latter have the $this being null issue. Another
complication when inlining methods is that we may only know the called
method if it is either private or final, i.e. there is no possibility of it
being overwritten in a child class.One tricky issue with inlining is that we need to unset all the variables
of the inlined function after the call, otherwise we may cause issues with
references and destruction order. If these unsets are not eliminated
through DCE they may be pretty expensive (for a larger number of vars).
Furthermore inlining increases the number of variables in the function
(which need to be initialized and destroyed), which may be problematic when
inlining into unlikely branches. (Register allocation for CVs would improve
this).Nikita