Struct wasmtime::PoolingAllocationConfig
source · pub struct PoolingAllocationConfig { /* private fields */ }
Expand description
Configuration options used with InstanceAllocationStrategy::Pooling
to
change the behavior of the pooling instance allocator.
This structure has a builder-style API in the same manner as Config
and
is configured with Config::allocation_strategy
.
Implementations§
source§impl PoolingAllocationConfig
impl PoolingAllocationConfig
sourcepub fn max_unused_warm_slots(&mut self, max: u32) -> &mut Self
pub fn max_unused_warm_slots(&mut self, max: u32) -> &mut Self
Configures the maximum number of “unused warm slots” to retain in the pooling allocator.
The pooling allocator operates over slots to allocate from, and each slot is considered “cold” if it’s never been used before or “warm” if it’s been used by some module in the past. Slots in the pooling allocator additionally track an “affinity” flag to a particular core wasm module. When a module is instantiated into a slot then the slot is considered affine to that module, even after the instance has been dealloocated.
When a new instance is created then a slot must be chosen, and the current algorithm for selecting a slot is:
-
If there are slots that are affine to the module being instantiated, then the most recently used slot is selected to be allocated from. This is done to improve reuse of resources such as memory mappings and additionally try to benefit from temporal locality for things like caches.
-
Otherwise if there are more than N affine slots to other modules, then one of those affine slots is chosen to be allocated. The slot chosen is picked on a least-recently-used basis.
-
Finally, if there are less than N affine slots to other modules, then the non-affine slots are allocated from.
This setting, max_unused_warm_slots
, is the value for N in the above
algorithm. The purpose of this setting is to have a knob over the RSS
impact of “unused slots” for a long-running wasm server.
If this setting is set to 0, for example, then affine slots are aggressively resused on a least-recently-used basis. A “cold” slot is only used if there are no affine slots available to allocate from. This means that the set of slots used over the lifetime of a program is the same as the maximum concurrent number of wasm instances.
If this setting is set to infinity, however, then cold slots are
prioritized to be allocated from. This means that the set of slots used
over the lifetime of a program will approach
PoolingAllocationConfig::instance_count
, or the maximum number of
slots in the pooling allocator.
Wasmtime does not aggressively decommit all resources associated with a
slot when the slot is not in use. For example the
PoolingAllocationConfig::linear_memory_keep_resident
option can be
used to keep memory associated with a slot, even when it’s not in use.
This means that the total set of used slots in the pooling instance
allocator can impact the overall RSS usage of a program.
The default value for this option is 100.
sourcepub fn linear_memory_keep_resident(&mut self, size: usize) -> &mut Self
pub fn linear_memory_keep_resident(&mut self, size: usize) -> &mut Self
How much memory, in bytes, to keep resident for each linear memory after deallocation.
This option is only applicable on Linux and has no effect on other platforms.
By default Wasmtime will use madvise
to reset the entire contents of
linear memory back to zero when a linear memory is deallocated. This
option can be used to use memset
instead to set memory back to zero
which can, in some configurations, reduce the number of page faults
taken when a slot is reused.
sourcepub fn table_keep_resident(&mut self, size: usize) -> &mut Self
pub fn table_keep_resident(&mut self, size: usize) -> &mut Self
How much memory, in bytes, to keep resident for each table after deallocation.
This option is only applicable on Linux and has no effect on other platforms.
This option is the same as
PoolingAllocationConfig::linear_memory_keep_resident
except that it
is applicable to tables instead.
sourcepub fn instance_count(&mut self, count: u32) -> &mut Self
pub fn instance_count(&mut self, count: u32) -> &mut Self
The maximum number of concurrent instances supported (default is 1000).
This value has a direct impact on the amount of memory allocated by the pooling instance allocator.
The pooling instance allocator allocates three memory pools with sizes depending on this value:
-
An instance pool, where each entry in the pool can store the runtime representation of an instance, including a maximal
VMContext
structure. -
A memory pool, where each entry in the pool contains the reserved address space for each linear memory supported by an instance.
-
A table pool, where each entry in the pool contains the space needed for each WebAssembly table supported by an instance (see
table_elements
to control the size of each table).
Additionally, this value will also control the maximum number of execution stacks allowed for asynchronous execution (one per instance), when enabled.
The memory pool will reserve a large quantity of host process address space to elide the bounds checks required for correct WebAssembly memory semantics. Even for 64-bit address spaces, the address space is limited when dealing with a large number of supported instances.
For example, on Linux x86_64, the userland address space limit is 128 TiB. That might seem like a lot, but each linear memory will reserve 6 GiB of space by default. Multiply that by the number of linear memories each instance supports and then by the number of supported instances and it becomes apparent that address space can be exhausted depending on the number of supported instances.
sourcepub fn instance_size(&mut self, size: usize) -> &mut Self
pub fn instance_size(&mut self, size: usize) -> &mut Self
The maximum size, in bytes, allocated for an instance and its
VMContext
.
This amount of space is pre-allocated for count
number of instances
and is used to store the runtime wasmtime_runtime::Instance
structure
along with its adjacent VMContext
structure. The Instance
type has a
static size but VMContext
is dynamically sized depending on the module
being instantiated. This size limit loosely correlates to the size of
the wasm module, taking into account factors such as:
- number of functions
- number of globals
- number of memories
- number of tables
- number of function types
If the allocated size per instance is too small then instantiation of a module will fail at runtime with an error indicating how many bytes were needed. This amount of bytes are committed to memory per-instance when a pooling allocator is created.
The default value for this is 1MB.
sourcepub fn instance_tables(&mut self, tables: u32) -> &mut Self
pub fn instance_tables(&mut self, tables: u32) -> &mut Self
The maximum number of defined tables for a module (default is 1).
This value controls the capacity of the VMTableDefinition
table in each instance’s
VMContext
structure.
The allocated size of the table will be tables * sizeof(VMTableDefinition)
for each
instance regardless of how many tables are defined by an instance’s module.
sourcepub fn instance_table_elements(&mut self, elements: u32) -> &mut Self
pub fn instance_table_elements(&mut self, elements: u32) -> &mut Self
The maximum table elements for any table defined in a module (default is 10000).
If a table’s minimum element limit is greater than this value, the module will fail to instantiate.
If a table’s maximum element limit is unbounded or greater than this value,
the maximum will be table_elements
for the purpose of any table.grow
instruction.
This value is used to reserve the maximum space for each supported table; table elements
are pointer-sized in the Wasmtime runtime. Therefore, the space reserved for each instance
is tables * table_elements * sizeof::<*const ()>
.
sourcepub fn instance_memories(&mut self, memories: u32) -> &mut Self
pub fn instance_memories(&mut self, memories: u32) -> &mut Self
The maximum number of defined linear memories for a module (default is 1).
This value controls the capacity of the VMMemoryDefinition
table in each instance’s
VMContext
structure.
The allocated size of the table will be memories * sizeof(VMMemoryDefinition)
for each
instance regardless of how many memories are defined by an instance’s module.
sourcepub fn instance_memory_pages(&mut self, pages: u64) -> &mut Self
pub fn instance_memory_pages(&mut self, pages: u64) -> &mut Self
The maximum number of pages for any linear memory defined in a module (default is 160).
The default of 160 means at most 10 MiB of host memory may be committed for each instance.
If a memory’s minimum page limit is greater than this value, the module will fail to instantiate.
If a memory’s maximum page limit is unbounded or greater than this value,
the maximum will be memory_pages
for the purpose of any memory.grow
instruction.
This value is used to control the maximum accessible space for each linear memory of an instance.
The reservation size of each linear memory is controlled by the
static_memory_maximum_size
setting and this value cannot
exceed the configured static memory maximum size.
Trait Implementations§
source§impl Clone for PoolingAllocationConfig
impl Clone for PoolingAllocationConfig
source§fn clone(&self) -> PoolingAllocationConfig
fn clone(&self) -> PoolingAllocationConfig
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for PoolingAllocationConfig
impl Debug for PoolingAllocationConfig
source§impl Default for PoolingAllocationConfig
impl Default for PoolingAllocationConfig
source§fn default() -> PoolingAllocationConfig
fn default() -> PoolingAllocationConfig
Auto Trait Implementations§
impl Freeze for PoolingAllocationConfig
impl RefUnwindSafe for PoolingAllocationConfig
impl Send for PoolingAllocationConfig
impl Sync for PoolingAllocationConfig
impl Unpin for PoolingAllocationConfig
impl UnwindSafe for PoolingAllocationConfig
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more