alexcrichton opened PR #3727 from no-type-in-func
to main
:
This commit changes the construction of a
Func
to lazily load the type
information if required instead of always loading the type information
atFunc
-construction time. The main purpose of this change is to
accelerate instantiation of instances which have many imports. Currently
in the fast way of doing this the instantiation loop looks like:let mut store = Store::new(&engine, ...); let instance = instance_pre.instantiate(&mut store);
In this situation the
instance_pre
will typically load host-defined
functions (defined viaLinker
APIs) into theStore
as individual
Func
items and then perform the instantiation process. The operation
of loading aHostFunc
into aStore
however currently involves two
expensive operations:
First a read-only lock is taken on the
RwLock
around engine
signatures.Next a clone of the wasm type is made to pull it out of the engine
signature registry.Neither of these is actually necessary for imported functions. The
FuncType
for imported functions is never used since all comparisons
happen with the intern'd indices instead. The only time aFuncType
is
used typically is for exported functions when usingFunc::typed
or
similar APIs which need type information.This commit makes this path faster by storing
Option<FuncType>
instead
ofFuncType
within aFunc
. This means that it starts out asNone
and is only filled in on-demand as necessary. This means that when
instantiating a module with many imports no clones/locks are done.On a simple microbenchmark where a module with 100 imports is
instantiated this PR improves instantiation time by ~35%. Due to the
rwlock used here and the general inefficiency of pthreads rwlocks the
effect is even more profound when many threads are performing the same
instantiation process. On x86_64 with 8 threads performing instantiation
this PR improves instantiation time by 80% and on arm64 it improves by
97% (wow read-contended glibc rwlocks on arm64 are slow).Note that much of the improvement here is also from memory
allocatoins/deallocations no longer being performed because dropping
functions within a store no longer requires deallocating theFuncType
if it's not present.A downside of this PR is that
Func::ty
is now unconditionally taking
an rwlock if the type hasn't already been filled in. (it uses the
engine). If this is an issue in the future though we can investigate at
that time using somthing like aOnce
to lazily fill in even when
mutable access to the store isn't available.<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
cfallin submitted PR review.
cfallin submitted PR review.
cfallin created PR review comment:
There's probably a mundane borrow-checker-subtlety reason for returning the downgraded immutable-borrow of
StoreOpaque
here, but could we add a comment describing why?
alexcrichton updated PR #3727 from no-type-in-func
to main
.
alexcrichton merged PR #3727.
Last updated: Dec 23 2024 at 12:05 UTC