lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> The receiver can only be specialized after the lookup of the
> variant (!) message. And the lookup is variant for each array
> element, too. There's no way the compiler can infer (or should
> predict) that 'array' only contains homogeneous objects.

If I were developing "static" compiler for the Lua, I would try
implement the following approach: always try to inline vararg
functions at callsites with a fixed number of arguments, then try to
unroll loops that iterate over varargs (apply a simple heuristic to
find such loops: index variable is in range 1 .. #args, index variable
is used in args[i]).

I am curious does it make sense? Can it be reformulated in terms of
tracing JIT?

Tracing JIT gets an inline for free. But I don't see how to implement
on-the-fly loop unrolling for this case.

(It seems that both Alexander's and Mark's examples will benefit from
this optimization)

--
e.v.e



On Thu, Nov 26, 2009 at 1:39 AM, Mike Pall <mikelu-0911@mike.de> wrote:
> Mark Hamburg wrote:
>> I would presume that the message send would optimize as well as
>> any message send -- though it's more unique because the message
>> is "unique" to the call.
>
> The receiver can only be specialized after the lookup of the
> variant (!) message. And the lookup is variant for each array
> element, too. There's no way the compiler can infer (or should
> predict) that 'array' only contains homogeneous objects.
>
> It *does* specialize to the first receiver it hits while
> recording. But if you call the same function with different
> messages and/or arrays which contain different object types, it
> needs to specialize to each receiver. This creates a binary
> decision tree *inside* the loop.
>
> So the above abstraction effectively creates a single megamorphic
> dispatch point, i.e. one or more unpredictable branches. That's
> not going to be fast, no matter what I come up with. Compilers
> don't like it, CPUs don't like it.
>
>> Would one be better off using code generation to build something
>> fitting the obj:msg( ... ) pattern?
>
> Definitely. Because 'msg' is a string constant and the receiver is
> usually the same. This makes specialization easy.
>
>> It just seems like the JIT logic should allow one to avoid
>> building custom functions via string manipulation and
>> loadstring. Or am I expecting too much of a tracing JIT?
>
> Yes and no. Yes, you can avoid this in most cases. But the shown
> abstraction has one indirection level the compiler cannot
> reasonably be expected to specialize away on its own. The 'hint'
> you see in your mind when looking at the code is just not present
> in the code.
>
> Equivalent code in C++ would probably use templates. Not just
> because the core languages lacks the expressiveness. But also
> because it explicitly tells the compiler how to create specialized
> copies of the code for each message.
>
>> I was also figuring that even without type information, there
>> ought to be a win in knowing how many arguments will be passed
>> to each call -- though here again code generation could also be
>> used if need be.
>
> Yes, but the vararg issue is mostly orthogonal to the dispatch
> issue.
>
> --Mike
>