[erlang-questions] Retrieving "semi-constant" data from a function versus Mnesia
Richard A. O'Keefe
ok@REDACTED
Thu May 14 04:24:47 CEST 2015
On 14/05/2015, at 10:58 am, Jay Nelson <jay@REDACTED> wrote:
> ROK wrote:
>
>> One of them is or was erts_find_export_entry(module, function, arity),
>> surprise surprise, which looks the triple up in a hash table, so it’s
>> fairly clear where the time is going.
>
> It’s funny because I recall from the CLOS "Art of the Metaobject Protocol”
> that this was a high-speed solution to the method dispatch problem. The
> memoization was bragging rights and what made it feasible.
Memoization in dynamic function calling is old technology.
As I recall, Smalltalk-80 used a cache for dynamic dispatch,
and later implementations used distributed "polymorphic inline
caches".
Simple inline caching would turn
Module:func(E1, ..., En)
into
static atomic { mod, ptr } cache;
atomic {
if (Module == cache.mod) {
p = cache.ptr;
} else {
p = lookup(Module, func, n);
cache.mod = Module;
cache.ptr = p;
}
}
(*p)(E1, ..., En);
One form of polymorphic inline caching would yield
static atomic { mod, ptr } cache[N];
q = &cache[hash(Module)%N];
atomic {
if (Module = q->mod) {
p = q->ptr;
} else {
p = lookup(Module, func, n);
q->mod = Module;
q->ptr = p;
}
}
(*p)(E1, ..., En);
This is typically implemented so that the cache can grow.
Doing this in a lock-free way is a bit tricky, but possible.
My actual point was that since a dynamic call in Erlang
involves at least two C function calls in addition to the
intended Erlang call, 6 times slower than a direct call
is not unreasonable.
Oh, that's emulated. I don't know what HiPE does with
dynamic function calls, but it *probably* makes normal
calls faster without touching dynamic ones much.
More information about the erlang-questions
mailing list