[Bf-blender-cvs] [17441b327b9] functions: use one block allocator per thread instead of per block

Jacques Lucke noreply at git.blender.org
Thu Jun 27 17:03:57 CEST 2019


Commit: 17441b327b9b85f93fc0e00b2d6f40dbb9a682e2
Author: Jacques Lucke
Date:   Thu Jun 27 17:03:44 2019 +0200
Branches: functions
https://developer.blender.org/rB17441b327b9b85f93fc0e00b2d6f40dbb9a682e2

use one block allocator per thread instead of per block

===================================================================

M	source/blender/simulations/bparticles/simulate.cpp

===================================================================

diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index cd5b4937f58..3f4bbbde9af 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -285,11 +285,11 @@ BLI_NOINLINE static void simulate_ignoring_events(ParticleSet particles,
   }
 }
 
-BLI_NOINLINE static void step_individual_particles(BlockAllocator &block_allocator,
-                                                   ParticleSet particles,
-                                                   ArrayRef<float> durations,
-                                                   float end_time,
-                                                   ParticleType &particle_type)
+BLI_NOINLINE static void step_particle_set(BlockAllocator &block_allocator,
+                                           ParticleSet particles,
+                                           ArrayRef<float> durations,
+                                           float end_time,
+                                           ParticleType &particle_type)
 {
   SmallVector<uint> unfinished_particle_indices;
   SmallVector<float> remaining_durations;
@@ -307,32 +307,78 @@ BLI_NOINLINE static void step_individual_particles(BlockAllocator &block_allocat
   simulate_ignoring_events(remaining_particles, remaining_durations, particle_type);
 }
 
+class BlockAllocators {
+ private:
+  ParticlesState &m_state;
+  SmallVector<BlockAllocator *> m_allocators;
+  SmallMap<int, BlockAllocator *> m_allocator_per_thread_id;
+  std::mutex m_access_mutex;
+
+ public:
+  BlockAllocators(ParticlesState &state) : m_state(state)
+  {
+  }
+
+  ~BlockAllocators()
+  {
+    for (BlockAllocator *allocator : m_allocators) {
+      delete allocator;
+    }
+  }
+
+  BlockAllocator &get_standalone_allocator()
+  {
+    BlockAllocator *new_allocator = new BlockAllocator(m_state);
+    m_allocators.append(new_allocator);
+    return *new_allocator;
+  }
+
+  BlockAllocator &get_threadlocal_allocator(int thread_id)
+  {
+    std::lock_guard<std::mutex> lock(m_access_mutex);
+
+    if (!m_allocator_per_thread_id.contains(thread_id)) {
+      BlockAllocator *new_allocator = new BlockAllocator(m_state);
+      m_allocators.append(new_allocator);
+      m_allocator_per_thread_id.add_new(thread_id, new_allocator);
+    }
+    return *m_allocator_per_thread_id.lookup(thread_id);
+  }
+
+  ArrayRef<BlockAllocator *> allocators()
+  {
+    return m_allocators;
+  }
+};
+
 struct StepBlocksParallelData {
   ArrayRef<ParticlesBlock *> blocks;
   ArrayRef<float> all_durations;
   float end_time;
   ParticleType &particle_type;
-  ParticlesState &particles_state;
+  BlockAllocators &block_allocators;
 };
 
-BLI_NOINLINE static void step_individual_particles_cb(
-    void *__restrict userdata, const int index, const ParallelRangeTLS *__restrict UNUSED(tls))
+BLI_NOINLINE static void step_individual_particles_cb(void *__restrict userdata,
+                                                      const int index,
+                                                      const ParallelRangeTLS *__restrict tls)
 {
   StepBlocksParallelData *data = (StepBlocksParallelData *)userdata;
   ParticlesBlock &block = *data->blocks[index];
 
-  BlockAllocator block_allocator(data->particles_state);
+  BlockAllocator block_allocator = data->block_allocators.get_threadlocal_allocator(
+      tls->thread_id);
 
   uint active_amount = block.active_amount();
   ParticleSet active_particles(block, static_number_range_ref(0, active_amount));
-  step_individual_particles(block_allocator,
-                            active_particles,
-                            data->all_durations.take_front(active_amount),
-                            data->end_time,
-                            data->particle_type);
+  step_particle_set(block_allocator,
+                    active_particles,
+                    data->all_durations.take_front(active_amount),
+                    data->end_time,
+                    data->particle_type);
 }
 
-BLI_NOINLINE static void step_individual_particles(ParticlesState &state,
+BLI_NOINLINE static void step_individual_particles(BlockAllocators &block_allocators,
                                                    ArrayRef<ParticlesBlock *> blocks,
                                                    TimeSpan time_span,
                                                    ParticleType &particle_type)
@@ -348,7 +394,8 @@ BLI_NOINLINE static void step_individual_particles(ParticlesState &state,
   SmallVector<float> all_durations(block_size);
   all_durations.fill(time_span.duration());
 
-  StepBlocksParallelData data = {blocks, all_durations, time_span.end(), particle_type, state};
+  StepBlocksParallelData data = {
+      blocks, all_durations, time_span.end(), particle_type, block_allocators};
 
   BLI_task_parallel_range(
       0, blocks.size(), (void *)&data, step_individual_particles_cb, &settings);
@@ -416,11 +463,11 @@ BLI_NOINLINE static void emit_new_particles_from_emitter(StepDescription &descri
       }
 
       ParticleSet emitted_particles(block, static_number_range_ref(range));
-      step_individual_particles(block_allocator,
-                                emitted_particles,
-                                initial_step_durations,
-                                time_span.end(),
-                                particle_type);
+      step_particle_set(block_allocator,
+                        emitted_particles,
+                        initial_step_durations,
+                        time_span.end(),
+                        particle_type);
 
       particle_count += emitted_particles.size();
     }
@@ -488,16 +535,19 @@ void simulate_step(ParticlesState &state, StepDescription &description)
   ensure_required_containers_exist(containers, description);
   ensure_required_attributes_exist(containers, description);
 
+  BlockAllocators block_allocators(state);
+
   for (uint type_id : description.particle_type_ids()) {
     ParticleType &type = description.particle_type(type_id);
     ParticlesContainer &container = *containers.lookup(type_id);
 
-    step_individual_particles(state, container.active_blocks().to_small_vector(), time_span, type);
+    step_individual_particles(
+        block_allocators, container.active_blocks().to_small_vector(), time_span, type);
   }
 
-  BlockAllocator block_allocator(state);
+  BlockAllocator &emitter_allocator = block_allocators.get_standalone_allocator();
   for (Emitter *emitter : description.emitters()) {
-    emit_new_particles_from_emitter(description, block_allocator, time_span, *emitter);
+    emit_new_particles_from_emitter(description, emitter_allocator, time_span, *emitter);
   }
 
   for (uint type_id : description.particle_type_ids()) {



More information about the Bf-blender-cvs mailing list