Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-06-25 19:52:55 +0300
committerJacques Lucke <jacques@blender.org>2022-06-25 19:53:26 +0300
commitb513c89e8450289746a7b3397bf3d610a0989d79 (patch)
treed2b930098bcca4bf158356d3783283a85d506dca /source
parentba1e97f1c6cd0c614a13eb1b5d7050b7c301d03e (diff)
Functions: avoid using Map for small values
This leads to a 5-10% performance improvement in my benchmark that runs a procedure many times on a single element.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_cpp_type.hh5
-rw-r--r--source/blender/functions/intern/multi_function_procedure_executor.cc24
2 files changed, 23 insertions, 6 deletions
diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh
index ed680214602..cc48b456da7 100644
--- a/source/blender/blenlib/BLI_cpp_type.hh
+++ b/source/blender/blenlib/BLI_cpp_type.hh
@@ -626,6 +626,11 @@ class CPPType : NonCopyable, NonMovable {
fill_construct_indices_(value, dst, mask);
}
+ bool can_exist_in_buffer(const int64_t buffer_size, const int64_t buffer_alignment) const
+ {
+ return size_ <= buffer_size && alignment_ <= buffer_alignment;
+ }
+
void print(const void *value, std::stringstream &ss) const
{
BLI_assert(this->pointer_can_point_to_instance(value));
diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc
index a45240dad55..d92ce80bceb 100644
--- a/source/blender/functions/intern/multi_function_procedure_executor.cc
+++ b/source/blender/functions/intern/multi_function_procedure_executor.cc
@@ -147,11 +147,11 @@ class ValueAllocator : NonCopyable, NonMovable {
Map<int, Stack<void *>> span_buffers_free_list_;
/** Cache buffers for single values of different types. */
+ static constexpr inline int small_value_max_size = 16;
+ static constexpr inline int small_value_max_alignment = 8;
+ Stack<void *> small_single_value_free_list_;
Map<const CPPType *, Stack<void *>> single_value_free_lists_;
- /** The cached memory buffers can hold #VariableState values. */
- Stack<void *> variable_state_free_list_;
-
public:
ValueAllocator(LinearAllocator<> &linear_allocator) : linear_allocator_(linear_allocator)
{
@@ -210,10 +210,15 @@ class ValueAllocator : NonCopyable, NonMovable {
VariableValue_OneSingle *obtain_OneSingle(const CPPType &type)
{
- Stack<void *> &stack = single_value_free_lists_.lookup_or_add_default(&type);
+ const bool is_small = type.can_exist_in_buffer(small_value_max_size,
+ small_value_max_alignment);
+ Stack<void *> &stack = is_small ? small_single_value_free_list_ :
+ single_value_free_lists_.lookup_or_add_default(&type);
void *buffer;
if (stack.is_empty()) {
- buffer = linear_allocator_.allocate(type.size(), type.alignment());
+ buffer = linear_allocator_.allocate(
+ std::max<int>(small_value_max_size, type.size()),
+ std::max<int>(small_value_max_alignment, type.alignment()));
}
else {
buffer = stack.pop();
@@ -259,7 +264,14 @@ class ValueAllocator : NonCopyable, NonMovable {
if (value_typed->is_initialized) {
type.destruct(value_typed->data);
}
- single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data);
+ const bool is_small = type.can_exist_in_buffer(small_value_max_size,
+ small_value_max_alignment);
+ if (is_small) {
+ small_single_value_free_list_.push(value_typed->data);
+ }
+ else {
+ single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data);
+ }
break;
}
case ValueType::OneVector: {