WIP: Functions: new local allocator for better memory reuse and performance #104630
|
@ -152,7 +152,7 @@ inline LocalAllocatorSet &LocalAllocator::owner_set()
|
|||
return owner_set_;
|
||||
}
|
||||
|
||||
BLI_NOINLINE inline void *LocalAllocator::allocate(const int64_t size, const int64_t alignment)
|
||||
inline void *LocalAllocator::allocate(const int64_t size, const int64_t alignment)
|
||||
{
|
||||
LocalAllocatorPool &pool = this->get_pool(size, alignment);
|
||||
BLI_assert(pool.element_size >= size);
|
||||
|
@ -161,9 +161,9 @@ BLI_NOINLINE inline void *LocalAllocator::allocate(const int64_t size, const int
|
|||
return this->allocate(pool);
|
||||
}
|
||||
|
||||
BLI_NOINLINE inline void LocalAllocator::deallocate(const void *buffer,
|
||||
const int64_t size,
|
||||
const int64_t alignment)
|
||||
inline void LocalAllocator::deallocate(const void *buffer,
|
||||
const int64_t size,
|
||||
const int64_t alignment)
|
||||
{
|
||||
LocalAllocatorPool &pool = this->get_pool(size, alignment);
|
||||
BLI_assert(pool.element_size >= size);
|
||||
|
|
|
@ -334,6 +334,7 @@ class FieldEvaluator : NonMovable, NonCopyable {
|
|||
ResourceScope scope_;
|
||||
const FieldContext &context_;
|
||||
const IndexMask mask_;
|
||||
LocalAllocator *allocator_ = nullptr;
|
||||
Vector<GField> fields_to_evaluate_;
|
||||
Vector<GVMutableArray> dst_varrays_;
|
||||
Vector<GVArray> evaluated_varrays_;
|
||||
|
@ -345,13 +346,18 @@ class FieldEvaluator : NonMovable, NonCopyable {
|
|||
|
||||
public:
|
||||
/** Takes #mask by pointer because the mask has to live longer than the evaluator. */
|
||||
FieldEvaluator(const FieldContext &context, const IndexMask *mask)
|
||||
: context_(context), mask_(*mask)
|
||||
FieldEvaluator(const FieldContext &context,
|
||||
const IndexMask *mask,
|
||||
LocalAllocator *allocator = nullptr)
|
||||
: context_(context), mask_(*mask), allocator_(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a field evaluator for all indices less than #size. */
|
||||
FieldEvaluator(const FieldContext &context, const int64_t size) : context_(context), mask_(size)
|
||||
FieldEvaluator(const FieldContext &context,
|
||||
const int64_t size,
|
||||
LocalAllocator *allocator = nullptr)
|
||||
: context_(context), mask_(size), allocator_(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -474,6 +480,7 @@ class FieldEvaluator : NonMovable, NonCopyable {
|
|||
* provided virtual arrays are returned.
|
||||
*/
|
||||
Vector<GVArray> evaluate_fields(ResourceScope &scope,
|
||||
LocalAllocator *allocator,
|
||||
Span<GFieldRef> fields_to_evaluate,
|
||||
IndexMask mask,
|
||||
const FieldContext &context,
|
||||
|
|
|
@ -277,6 +277,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
|
|||
}
|
||||
|
||||
Vector<GVArray> evaluate_fields(ResourceScope &scope,
|
||||
LocalAllocator *allocator,
|
||||
Span<GFieldRef> fields_to_evaluate,
|
||||
IndexMask mask,
|
||||
const FieldContext &context,
|
||||
|
@ -372,7 +373,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope,
|
|||
MFProcedureExecutor procedure_executor{procedure};
|
||||
|
||||
MFParamsBuilder mf_params{procedure_executor, &mask};
|
||||
MFContextBuilder mf_context;
|
||||
MFContextBuilder mf_context{allocator};
|
||||
|
||||
/* Provide inputs to the procedure executor. */
|
||||
for (const GVArray &varray : field_context_inputs) {
|
||||
|
@ -423,7 +424,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope,
|
|||
procedure, scope, field_tree_info, constant_fields_to_evaluate);
|
||||
MFProcedureExecutor procedure_executor{procedure};
|
||||
MFParamsBuilder mf_params{procedure_executor, 1};
|
||||
MFContextBuilder mf_context;
|
||||
MFContextBuilder mf_context{allocator};
|
||||
|
||||
/* Provide inputs to the procedure executor. */
|
||||
for (const GVArray &varray : field_context_inputs) {
|
||||
|
@ -500,7 +501,7 @@ void evaluate_constant_field(const GField &field, void *r_value)
|
|||
|
||||
ResourceScope scope;
|
||||
FieldContext context;
|
||||
Vector<GVArray> varrays = evaluate_fields(scope, {field}, IndexRange(1), context);
|
||||
Vector<GVArray> varrays = evaluate_fields(scope, nullptr, {field}, IndexRange(1), context);
|
||||
varrays[0].get_to_uninitialized(0, r_value);
|
||||
}
|
||||
|
||||
|
@ -771,11 +772,12 @@ int FieldEvaluator::add(GField field)
|
|||
static IndexMask evaluate_selection(const Field<bool> &selection_field,
|
||||
const FieldContext &context,
|
||||
IndexMask full_mask,
|
||||
ResourceScope &scope)
|
||||
ResourceScope &scope,
|
||||
LocalAllocator *allocator)
|
||||
{
|
||||
if (selection_field) {
|
||||
VArray<bool> selection =
|
||||
evaluate_fields(scope, {selection_field}, full_mask, context)[0].typed<bool>();
|
||||
evaluate_fields(scope, allocator, {selection_field}, full_mask, context)[0].typed<bool>();
|
||||
return index_mask_from_selection(full_mask, selection, scope);
|
||||
}
|
||||
return full_mask;
|
||||
|
@ -785,13 +787,14 @@ void FieldEvaluator::evaluate()
|
|||
{
|
||||
BLI_assert_msg(!is_evaluated_, "Cannot evaluate fields twice.");
|
||||
|
||||
selection_mask_ = evaluate_selection(selection_field_, context_, mask_, scope_);
|
||||
selection_mask_ = evaluate_selection(selection_field_, context_, mask_, scope_, allocator_);
|
||||
|
||||
Array<GFieldRef> fields(fields_to_evaluate_.size());
|
||||
for (const int i : fields_to_evaluate_.index_range()) {
|
||||
fields[i] = fields_to_evaluate_[i];
|
||||
}
|
||||
evaluated_varrays_ = evaluate_fields(scope_, fields, selection_mask_, context_, dst_varrays_);
|
||||
evaluated_varrays_ = evaluate_fields(
|
||||
scope_, allocator_, fields, selection_mask_, context_, dst_varrays_);
|
||||
BLI_assert(fields_to_evaluate_.size() == evaluated_varrays_.size());
|
||||
for (const int i : fields_to_evaluate_.index_range()) {
|
||||
OutputPointerInfo &info = output_pointer_infos_[i];
|
||||
|
|
|
@ -263,7 +263,7 @@ TEST(field, SameFieldTwice)
|
|||
IndexMask mask{IndexRange(2)};
|
||||
ResourceScope scope;
|
||||
Vector<GVArray> results = evaluate_fields(
|
||||
scope, {constant_field, constant_field}, mask, field_context);
|
||||
scope, nullptr, {constant_field, constant_field}, mask, field_context);
|
||||
|
||||
VArray<int> varray1 = results[0].typed<int>();
|
||||
VArray<int> varray2 = results[1].typed<int>();
|
||||
|
|
Loading…
Reference in New Issue