[Bf-blender-cvs] [d34c240ebf4] functions: Cache particle blocks in container for reuse
Jacques Lucke
noreply at git.blender.org
Wed Jul 10 12:00:57 CEST 2019
Commit: d34c240ebf40aac87aeae732184ddee4f89e65c3
Author: Jacques Lucke
Date: Wed Jul 10 11:05:46 2019 +0200
Branches: functions
https://developer.blender.org/rBd34c240ebf40aac87aeae732184ddee4f89e65c3
Cache particle blocks in container for reuse
===================================================================
M source/blender/blenlib/BLI_small_stack.hpp
M source/blender/blenlib/BLI_small_vector.hpp
M source/blender/simulations/bparticles/particles_container.cpp
M source/blender/simulations/bparticles/particles_container.hpp
M source/blender/simulations/bparticles/simulate.cpp
===================================================================
diff --git a/source/blender/blenlib/BLI_small_stack.hpp b/source/blender/blenlib/BLI_small_stack.hpp
index 31555dbcd43..fe6667e8bd5 100644
--- a/source/blender/blenlib/BLI_small_stack.hpp
+++ b/source/blender/blenlib/BLI_small_stack.hpp
@@ -42,6 +42,11 @@ template<typename T, uint N = 4> class SmallStack {
{
}
+ operator ArrayRef<T>()
+ {
+ return m_elements;
+ }
+
/**
* Return the number of elements in the stack.
*/
diff --git a/source/blender/blenlib/BLI_small_vector.hpp b/source/blender/blenlib/BLI_small_vector.hpp
index 64c2e7ee75e..ffa275973b5 100644
--- a/source/blender/blenlib/BLI_small_vector.hpp
+++ b/source/blender/blenlib/BLI_small_vector.hpp
@@ -261,6 +261,11 @@ template<typename T, uint N = 4> class SmallVector {
this->extend(other.begin(), other.size());
}
+ void extend(ArrayRef<T> array)
+ {
+ this->extend(array.begin(), array.size());
+ }
+
void extend(const T *start, uint amount)
{
this->reserve(m_size + amount);
diff --git a/source/blender/simulations/bparticles/particles_container.cpp b/source/blender/simulations/bparticles/particles_container.cpp
index 318ec66ec43..01f064f9938 100644
--- a/source/blender/simulations/bparticles/particles_container.cpp
+++ b/source/blender/simulations/bparticles/particles_container.cpp
@@ -1,5 +1,9 @@
+#include "BLI_timeit.hpp"
+
#include "particles_container.hpp"
+#define CACHED_BLOCKS_PER_CONTAINER 5
+
namespace BParticles {
ParticlesBlock::ParticlesBlock(ParticlesContainer &container, AttributeArraysCore &attributes_core)
@@ -14,21 +18,28 @@ ParticlesContainer::ParticlesContainer(AttributesInfo attributes, uint block_siz
ParticlesContainer::~ParticlesContainer()
{
- while (m_blocks.size() > 0) {
- ParticlesBlock *block = m_blocks.any();
- block->clear();
- this->release_block(*block);
+ for (ParticlesBlock *block : m_active_blocks) {
+ this->free_block(block);
+ }
+ for (ParticlesBlock *block : m_cached_blocks) {
+ this->free_block(block);
}
}
ParticlesBlock &ParticlesContainer::new_block()
{
+ SCOPED_TIMER(__func__);
+
std::lock_guard<std::mutex> lock(m_blocks_mutex);
- AttributeArraysCore attributes_core = AttributeArraysCore::NewWithSeparateAllocations(
- m_attributes_info, m_block_size);
- ParticlesBlock *block = new ParticlesBlock(*this, attributes_core);
- m_blocks.add_new(block);
+ if (!m_cached_blocks.empty()) {
+ ParticlesBlock *block = m_cached_blocks.pop();
+ m_active_blocks.add_new(block);
+ return *block;
+ }
+
+ ParticlesBlock *block = this->allocate_block();
+ m_active_blocks.add_new(block);
return *block;
}
@@ -37,12 +48,30 @@ void ParticlesContainer::release_block(ParticlesBlock &block)
std::lock_guard<std::mutex> lock(m_blocks_mutex);
BLI_assert(block.active_amount() == 0);
- BLI_assert(m_blocks.contains(&block));
+ BLI_assert(m_active_blocks.contains(&block));
BLI_assert(&block.container() == this);
- block.attributes_core().free_buffers();
- m_blocks.remove(&block);
- delete █
+ m_active_blocks.remove(&block);
+ if (m_cached_blocks.size() < CACHED_BLOCKS_PER_CONTAINER) {
+ m_cached_blocks.push(&block);
+ }
+ else {
+ this->free_block(&block);
+ }
+}
+
+ParticlesBlock *ParticlesContainer::allocate_block()
+{
+ AttributeArraysCore attributes_core = AttributeArraysCore::NewWithSeparateAllocations(
+ m_attributes_info, m_block_size);
+ ParticlesBlock *block = new ParticlesBlock(*this, attributes_core);
+ return block;
+}
+
+void ParticlesContainer::free_block(ParticlesBlock *block)
+{
+ block->attributes_core().free_buffers();
+ delete block;
}
static SmallVector<int> map_attribute_indices(AttributesInfo &from_info, AttributesInfo &to_info)
@@ -93,7 +122,11 @@ void ParticlesContainer::update_attributes(AttributesInfo new_info)
SmallVector<void *> arrays;
arrays.reserve(new_info.amount());
- for (ParticlesBlock *block : m_blocks) {
+
+ SmallVector<ParticlesBlock *> all_blocks;
+ all_blocks.extend(m_active_blocks);
+ all_blocks.extend(m_cached_blocks);
+ for (ParticlesBlock *block : all_blocks) {
arrays.clear();
for (uint new_index : new_info.attribute_indices()) {
@@ -127,7 +160,7 @@ void ParticlesContainer::flatten_attribute_data(StringRef attribute_name, void *
uint element_size = size_of_attribute_type(m_attributes_info.type_of(attribute_index));
uint offset = 0;
- for (ParticlesBlock *block : m_blocks) {
+ for (ParticlesBlock *block : m_active_blocks) {
uint amount = block->active_amount();
void *src = block->attributes().get_ptr(attribute_index);
memcpy(POINTER_OFFSET(dst, offset), src, amount * element_size);
diff --git a/source/blender/simulations/bparticles/particles_container.hpp b/source/blender/simulations/bparticles/particles_container.hpp
index a833573e134..ea91000ab68 100644
--- a/source/blender/simulations/bparticles/particles_container.hpp
+++ b/source/blender/simulations/bparticles/particles_container.hpp
@@ -3,6 +3,7 @@
#include <mutex>
#include "BLI_small_map.hpp"
+#include "BLI_small_stack.hpp"
#include "attributes.hpp"
@@ -10,6 +11,7 @@ namespace BParticles {
using BLI::SmallMap;
using BLI::SmallSet;
+using BLI::SmallStack;
class ParticlesContainer;
class ParticlesBlock;
@@ -25,7 +27,8 @@ class ParticlesBlock;
class ParticlesContainer {
private:
AttributesInfo m_attributes_info;
- SmallSet<ParticlesBlock *> m_blocks;
+ SmallSetVector<ParticlesBlock *> m_active_blocks;
+ SmallStack<ParticlesBlock *> m_cached_blocks;
uint m_block_size;
std::mutex m_blocks_mutex;
@@ -59,7 +62,7 @@ class ParticlesContainer {
/**
* Get a read-only buffer of all the blocks currently in use.
*/
- const SmallSet<ParticlesBlock *> &active_blocks();
+ ArrayRef<ParticlesBlock *> active_blocks();
/**
* Create a new block in this container. It safe to call this function from separate threads at
@@ -85,6 +88,10 @@ class ParticlesContainer {
SmallVector<float3> flatten_attribute_float3(StringRef attribute_name);
friend bool operator==(const ParticlesContainer &a, const ParticlesContainer &b);
+
+ private:
+ ParticlesBlock *allocate_block();
+ void free_block(ParticlesBlock *block);
};
/**
@@ -201,7 +208,7 @@ inline uint ParticlesContainer::block_size() const
inline uint ParticlesContainer::count_active() const
{
uint count = 0;
- for (ParticlesBlock *block : m_blocks) {
+ for (ParticlesBlock *block : m_active_blocks) {
count += block->active_amount();
}
return count;
@@ -212,9 +219,9 @@ inline AttributesInfo &ParticlesContainer::attributes_info()
return m_attributes_info;
}
-inline const SmallSet<ParticlesBlock *> &ParticlesContainer::active_blocks()
+inline ArrayRef<ParticlesBlock *> ParticlesContainer::active_blocks()
{
- return m_blocks;
+ return m_active_blocks;
}
inline bool operator==(const ParticlesContainer &a, const ParticlesContainer &b)
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index cd2754ac4e6..214ed7f9b10 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -618,14 +618,14 @@ BLI_NOINLINE static void delete_tagged_particles(ParticlesState &state,
USE_THREADING);
}
-BLI_NOINLINE static void compress_all_blocks(ParticlesContainer &particles)
+BLI_NOINLINE static void compress_all_blocks(ParticlesContainer &container)
{
- SmallVector<ParticlesBlock *> blocks = particles.active_blocks().to_small_vector();
+ SmallVector<ParticlesBlock *> blocks = container.active_blocks();
ParticlesBlock::Compress(blocks);
for (ParticlesBlock *block : blocks) {
if (block->is_empty()) {
- particles.release_block(*block);
+ container.release_block(*block);
}
}
}
More information about the Bf-blender-cvs
mailing list