WIP: Functions: new local allocator for better memory reuse and performance #104630
|
@ -284,7 +284,7 @@ class LazyFunction {
|
|||
/**
|
||||
* Destruct the storage created in #init_storage.
|
||||
*/
|
||||
virtual void destruct_storage(void *storage) const;
|
||||
virtual void destruct_storage(void *storage, LocalPool<> &allocator) const;
|
||||
|
||||
/**
|
||||
* Calls `fn` with the input indices that the given `output_index` may depend on. By default
|
||||
|
|
|
@ -93,7 +93,7 @@ inline void execute_lazy_function_eagerly_impl(
|
|||
BasicParams params{
|
||||
fn, input_pointers, output_pointers, input_usages, output_usages, set_outputs};
|
||||
fn.execute(params, context);
|
||||
fn.destruct_storage(context.storage);
|
||||
fn.destruct_storage(context.storage, allocator);
|
||||
|
||||
/* Make sure all outputs have been computed. */
|
||||
BLI_assert(!Span(set_outputs).contains(false));
|
||||
|
|
|
@ -89,7 +89,7 @@ class GraphExecutor : public LazyFunction {
|
|||
const SideEffectProvider *side_effect_provider);
|
||||
|
||||
void *init_storage(LocalPool<> &allocator) const override;
|
||||
void destruct_storage(void *storage) const override;
|
||||
void destruct_storage(void *storage, LocalPool<> &allocator) const override;
|
||||
|
||||
private:
|
||||
void execute_impl(Params ¶ms, const Context &context) const override;
|
||||
|
|
|
@ -30,7 +30,7 @@ void *LazyFunction::init_storage(LocalPool<> & /*allocator*/) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void LazyFunction::destruct_storage(void *storage) const
|
||||
void LazyFunction::destruct_storage(void *storage, LocalPool<> & /*allocator*/) const
|
||||
{
|
||||
BLI_assert(storage == nullptr);
|
||||
UNUSED_VARS_NDEBUG(storage);
|
||||
|
|
|
@ -267,7 +267,7 @@ class Executor {
|
|||
BLI_assert(self_.graph_.node_indices_are_valid());
|
||||
}
|
||||
|
||||
~Executor()
|
||||
void destruct_self(LocalPool<> & /*parent_allocator*/)
|
||||
{
|
||||
if (TaskPool *task_pool = task_pool_.load()) {
|
||||
BLI_task_pool_free(task_pool);
|
||||
|
@ -276,9 +276,10 @@ class Executor {
|
|||
for (const int node_index : range) {
|
||||
const Node &node = *self_.graph_.nodes()[node_index];
|
||||
NodeState &node_state = *node_states_[node_index];
|
||||
this->destruct_node_state(node, node_state);
|
||||
this->destruct_node_state(node, node_state, this->get_main_or_local_allocator());
|
||||
}
|
||||
});
|
||||
this->~Executor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -364,15 +365,14 @@ class Executor {
|
|||
node_state.outputs = allocator.construct_array<OutputState>(node_outputs.size());
|
||||
}
|
||||
|
||||
void destruct_node_state(const Node &node, NodeState &node_state)
|
||||
void destruct_node_state(const Node &node, NodeState &node_state, LocalPool<> &allocator)
|
||||
{
|
||||
if (node.is_function()) {
|
||||
const LazyFunction &fn = static_cast<const FunctionNode &>(node).function();
|
||||
if (node_state.storage != nullptr) {
|
||||
fn.destruct_storage(node_state.storage);
|
||||
fn.destruct_storage(node_state.storage, allocator);
|
||||
}
|
||||
}
|
||||
LocalPool<> &allocator = this->get_main_or_local_allocator();
|
||||
for (const int i : node.inputs().index_range()) {
|
||||
InputState &input_state = node_state.inputs[i];
|
||||
const InputSocket &input_socket = node.input(i);
|
||||
|
@ -891,7 +891,7 @@ class Executor {
|
|||
if (node_state.storage != nullptr) {
|
||||
if (node.is_function()) {
|
||||
const FunctionNode &fn_node = static_cast<const FunctionNode &>(node);
|
||||
fn_node.function().destruct_storage(node_state.storage);
|
||||
fn_node.function().destruct_storage(node_state.storage, allocator);
|
||||
}
|
||||
node_state.storage = nullptr;
|
||||
}
|
||||
|
@ -1337,9 +1337,11 @@ void *GraphExecutor::init_storage(LocalPool<> &allocator) const
|
|||
return &executor;
|
||||
}
|
||||
|
||||
void GraphExecutor::destruct_storage(void *storage) const
|
||||
void GraphExecutor::destruct_storage(void *storage, LocalPool<> &allocator) const
|
||||
{
|
||||
std::destroy_at(static_cast<Executor *>(storage));
|
||||
Executor *executor = static_cast<Executor *>(storage);
|
||||
executor->destruct_self(allocator);
|
||||
allocator.deallocate(executor, sizeof(Executor), alignof(Executor));
|
||||
}
|
||||
|
||||
void GraphExecutorLogger::log_socket_value(const Socket &socket,
|
||||
|
|
|
@ -1199,7 +1199,7 @@ static GeometrySet compute_geometry(
|
|||
param_output_usages,
|
||||
param_set_outputs};
|
||||
graph_executor.execute(lf_params, lf_context);
|
||||
graph_executor.destruct_storage(lf_context.storage);
|
||||
graph_executor.destruct_storage(lf_context.storage, allocator);
|
||||
|
||||
for (GMutablePointer &ptr : inputs_to_destruct) {
|
||||
ptr.destruct();
|
||||
|
|
|
@ -696,10 +696,10 @@ class LazyFunctionForGroupNode : public LazyFunction {
|
|||
return s;
|
||||
}
|
||||
|
||||
void destruct_storage(void *storage) const override
|
||||
void destruct_storage(void *storage, LocalPool<> &allocator) const override
|
||||
{
|
||||
Storage *s = static_cast<Storage *>(storage);
|
||||
graph_executor_->destruct_storage(s->graph_executor_storage);
|
||||
graph_executor_->destruct_storage(s->graph_executor_storage, allocator);
|
||||
std::destroy_at(s);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue