[Bf-blender-cvs] [b60dcf97657] functions: store fixed array allocator per thread
Jacques Lucke
noreply at git.blender.org
Sun Jun 30 16:00:59 CEST 2019
Commit: b60dcf9765717ddbef62af9d98e8a50cfb5f79b0
Author: Jacques Lucke
Date: Sun Jun 30 11:51:03 2019 +0200
Branches: functions
https://developer.blender.org/rBb60dcf9765717ddbef62af9d98e8a50cfb5f79b0
store fixed array allocator per thread
===================================================================
M source/blender/simulations/bparticles/attributes.cpp
M source/blender/simulations/bparticles/attributes.hpp
M source/blender/simulations/bparticles/simulate.cpp
===================================================================
diff --git a/source/blender/simulations/bparticles/attributes.cpp b/source/blender/simulations/bparticles/attributes.cpp
index f51b32fcc4f..bec1e08be18 100644
--- a/source/blender/simulations/bparticles/attributes.cpp
+++ b/source/blender/simulations/bparticles/attributes.cpp
@@ -66,4 +66,13 @@ void AttributeArraysCore::free_buffers()
}
}
+void AttributeArraysCore::deallocate_in_array_allocator(FixedArrayAllocator &allocator)
+{
+ for (uint i = 0; i < m_arrays.size(); i++) {
+ void *ptr = m_arrays[i];
+ uint element_size = size_of_attribute_type(m_info->type_of(i));
+ allocator.deallocate_array(ptr, element_size);
+ }
+}
+
}; // namespace BParticles
diff --git a/source/blender/simulations/bparticles/attributes.hpp b/source/blender/simulations/bparticles/attributes.hpp
index b3750a3e18b..ef46c3c1102 100644
--- a/source/blender/simulations/bparticles/attributes.hpp
+++ b/source/blender/simulations/bparticles/attributes.hpp
@@ -147,9 +147,11 @@ class AttributeArraysCore {
~AttributeArraysCore();
static AttributeArraysCore NewWithSeparateAllocations(AttributesInfo &info, uint size);
+ void free_buffers();
+
static AttributeArraysCore NewWithArrayAllocator(AttributesInfo &info,
FixedArrayAllocator &allocator);
- void free_buffers();
+ void deallocate_in_array_allocator(FixedArrayAllocator &allocator);
AttributesInfo &info();
void *get_ptr(uint index);
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index ee678bc6f2f..b538f196658 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -398,14 +398,14 @@ BLI_NOINLINE static void simulate_block(FixedArrayAllocator &array_allocator,
ParticleSet remaining_particles(block, unfinished_particle_indices);
apply_remaining_offsets(remaining_particles, attribute_offsets);
}
+
+ attribute_offsets_core.deallocate_in_array_allocator(array_allocator);
}
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)
@@ -419,27 +419,13 @@ class BlockAllocators {
}
}
- BlockAllocator &get_standalone_allocator()
+ BlockAllocator &new_allocator()
{
- std::lock_guard<std::mutex> lock(m_access_mutex);
-
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;
@@ -455,12 +441,25 @@ class BlockAllocators {
}
};
+struct ThreadLocalData {
+ FixedArrayAllocator array_allocator;
+ BlockAllocator &block_allocator;
+
+ ThreadLocalData(uint block_size, BlockAllocator &block_allocator)
+ : array_allocator(block_size), block_allocator(block_allocator)
+ {
+ }
+};
+
struct SimulateTimeSpanData {
ArrayRef<ParticlesBlock *> blocks;
ArrayRef<float> all_durations;
float end_time;
BlockAllocators &block_allocators;
StepDescription &step_description;
+
+ std::mutex data_per_thread_mutex;
+ SmallMap<uint, ThreadLocalData *> data_per_thread;
};
BLI_NOINLINE static void simulate_block_time_span_cb(void *__restrict userdata,
@@ -468,19 +467,28 @@ BLI_NOINLINE static void simulate_block_time_span_cb(void *__restrict userdata,
const ParallelRangeTLS *__restrict tls)
{
SCOPED_TIMER_STATS(__func__);
-
SimulateTimeSpanData *data = (SimulateTimeSpanData *)userdata;
- BlockAllocator &block_allocator = data->block_allocators.get_threadlocal_allocator(
- tls->thread_id);
+ ThreadLocalData *my_data;
+ {
+ std::lock_guard<std::mutex> lock(data->data_per_thread_mutex);
+ if (!data->data_per_thread.contains(tls->thread_id)) {
+ ThreadLocalData *new_data = new ThreadLocalData(BLOCK_SIZE,
+ data->block_allocators.new_allocator());
+ data->data_per_thread.add_new(tls->thread_id, new_data);
+ }
+
+ my_data = data->data_per_thread.lookup(tls->thread_id);
+ }
+
+ BlockAllocator &block_allocator = my_data->block_allocator;
+ FixedArrayAllocator &array_allocator = my_data->array_allocator;
ParticlesBlock &block = *data->blocks[index];
ParticlesState &state = block_allocator.particles_state();
uint particle_type_id = state.particle_container_id(block.container());
ParticleType &particle_type = data->step_description.particle_type(particle_type_id);
- FixedArrayAllocator array_allocator(block.container().block_size());
-
simulate_block(array_allocator,
block_allocator,
block,
@@ -507,9 +515,13 @@ BLI_NOINLINE static void simulate_blocks_for_time_span(BlockAllocators &block_al
all_durations.fill(time_span.duration());
SimulateTimeSpanData data = {
- blocks, all_durations, time_span.end(), block_allocators, step_description};
+ blocks, all_durations, time_span.end(), block_allocators, step_description, {}, {}};
BLI_task_parallel_range(0, blocks.size(), (void *)&data, simulate_block_time_span_cb, &settings);
+
+ for (ThreadLocalData *local_data : data.data_per_thread.values()) {
+ delete local_data;
+ }
}
struct SimulateFromBirthData {
@@ -517,6 +529,9 @@ struct SimulateFromBirthData {
float end_time;
BlockAllocators &block_allocators;
StepDescription &step_description;
+
+ std::mutex data_per_thread_mutex;
+ SmallMap<uint, ThreadLocalData *> data_per_thread;
};
BLI_NOINLINE static void simulate_block_from_birth_cb(void *__restrict userdata,
@@ -525,14 +540,24 @@ BLI_NOINLINE static void simulate_block_from_birth_cb(void *__restrict userdata,
{
SimulateFromBirthData *data = (SimulateFromBirthData *)userdata;
- BlockAllocator &block_allocator = data->block_allocators.get_threadlocal_allocator(
- tls->thread_id);
+ ThreadLocalData *my_data;
+ {
+ std::lock_guard<std::mutex> lock(data->data_per_thread_mutex);
+ if (!data->data_per_thread.contains(tls->thread_id)) {
+ ThreadLocalData *new_data = new ThreadLocalData(BLOCK_SIZE,
+ data->block_allocators.new_allocator());
+ data->data_per_thread.add_new(tls->thread_id, new_data);
+ }
+
+ my_data = data->data_per_thread.lookup(tls->thread_id);
+ }
+
+ FixedArrayAllocator &array_allocator = my_data->array_allocator;
+ BlockAllocator &block_allocator = my_data->block_allocator;
ParticlesBlock &block = *data->blocks[index];
ParticlesState &state = block_allocator.particles_state();
- FixedArrayAllocator array_allocator(block.container().block_size());
-
uint particle_type_id = state.particle_container_id(block.container());
ParticleType &particle_type = data->step_description.particle_type(particle_type_id);
@@ -560,9 +585,13 @@ BLI_NOINLINE static void simulate_blocks_from_birth_to_current_time(
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = USE_THREADING;
- SimulateFromBirthData data = {blocks, end_time, block_allocators, step_description};
+ SimulateFromBirthData data = {blocks, end_time, block_allocators, step_description, {}, {}};
BLI_task_parallel_range(
0, blocks.size(), (void *)&data, simulate_block_from_birth_cb, &settings);
+
+ for (ThreadLocalData *local_data : data.data_per_thread.values()) {
+ delete local_data;
+ }
}
/* Delete particles.
@@ -683,7 +712,7 @@ BLI_NOINLINE static void create_particles_from_emitters(StepDescription &step_de
BlockAllocators &block_allocators,
TimeSpan time_span)
{
- BlockAllocator &emitter_allocator = block_allocators.get_standalone_allocator();
+ BlockAllocator &emitter_allocator = block_allocators.new_allocator();
for (Emitter *emitter : step_description.emitters()) {
EmitterInterface interface(emitter_allocator, time_span);
emitter->emit(interface);
More information about the Bf-blender-cvs
mailing list