[Bf-blender-cvs] [50afb13ee09] profiler-editor: use linear allocator for task names

Jacques Lucke noreply at git.blender.org
Sat May 1 13:30:33 CEST 2021


Commit: 50afb13ee09cc62a32dd5160e7e02cd75bbd23f8
Author: Jacques Lucke
Date:   Sat May 1 12:08:20 2021 +0200
Branches: profiler-editor
https://developer.blender.org/rB50afb13ee09cc62a32dd5160e7e02cd75bbd23f8

use linear allocator for task names

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

M	source/blender/blenlib/BLI_linear_allocator.hh
M	source/blender/blenlib/BLI_profile_manage.hh
M	source/blender/blenlib/BLI_single_producer_chunk_consumer.hh
M	source/blender/blenlib/intern/profile.cc

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

diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index 6aa97d5c5e7..bd883c1de16 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -33,8 +33,8 @@ namespace blender {
 template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopyable, NonMovable {
  private:
   Allocator allocator_;
-  Vector<void *> owned_buffers_;
-  Vector<Span<char>> unused_borrowed_buffers_;
+  Vector<void *, 4, Allocator> owned_buffers_;
+  Vector<Span<char>, 1, Allocator> unused_borrowed_buffers_;
 
   uintptr_t current_begin_;
   uintptr_t current_end_;
@@ -89,9 +89,29 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
       this->allocate_new_buffer(size + alignment, alignment);
       return this->allocate(size, alignment);
     }
-    return this->allocator_large_buffer(size, alignment);
+    return this->allocate_large_buffer(size, alignment);
   };
 
+  void *allocate_unaligned(const int64_t size)
+  {
+    BLI_assert(size >= 0);
+
+    const uint64_t potential_allocation_begin = current_begin_;
+    const uint64_t potential_allocation_end = potential_allocation_begin + size;
+    if (potential_allocation_end <= current_end_) {
+#ifdef DEBUG
+      debug_allocated_amount_ += size;
+#endif
+      current_begin_ = potential_allocation_end;
+      return reinterpret_cast<void *>(potential_allocation_begin);
+    }
+    if (size <= large_buffer_threshold) {
+      this->allocate_new_buffer(size, 1);
+      return this->allocate_unaligned(size);
+    }
+    return this->allocate_large_buffer(size, 1);
+  }
+
   /**
    * Allocate a memory buffer that can hold an instance of T.
    *
@@ -147,10 +167,12 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
    */
   StringRefNull copy_string(StringRef str)
   {
-    const int64_t alloc_size = str.size() + 1;
-    char *buffer = static_cast<char *>(this->allocate(alloc_size, 1));
-    str.copy(buffer, alloc_size);
-    return StringRefNull(static_cast<const char *>(buffer));
+    const int64_t str_size = str.size();
+    const int64_t alloc_size = str_size + 1;
+    char *buffer = static_cast<char *>(this->allocate_unaligned(alloc_size));
+    memcpy(buffer, str.data(), str_size);
+    buffer[str_size] = '\0';
+    return StringRefNull(buffer, str_size);
   }
 
   MutableSpan<void *> allocate_elements_and_pointer_array(int64_t element_amount,
@@ -229,7 +251,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
     current_end_ = current_begin_ + size_in_bytes;
   }
 
-  void *allocator_large_buffer(const int64_t size, const int64_t alignment)
+  void *allocate_large_buffer(const int64_t size, const int64_t alignment)
   {
     void *buffer = allocator_.allocate(size, alignment, __func__);
     owned_buffers_.append(buffer);
diff --git a/source/blender/blenlib/BLI_profile_manage.hh b/source/blender/blenlib/BLI_profile_manage.hh
index 3028efeb36c..5ceb4429d04 100644
--- a/source/blender/blenlib/BLI_profile_manage.hh
+++ b/source/blender/blenlib/BLI_profile_manage.hh
@@ -29,8 +29,7 @@ using TimePoint = Clock::time_point;
 using Nanoseconds = std::chrono::nanoseconds;
 
 struct ProfileTaskBegin {
-  /* TODO: Don't use std::string when name is statically allocated. */
-  std::string name;
+  const char *name;
   TimePoint time;
   uint64_t id;
   uint64_t parent_id;
diff --git a/source/blender/blenlib/BLI_single_producer_chunk_consumer.hh b/source/blender/blenlib/BLI_single_producer_chunk_consumer.hh
index 6f1ba00248e..31fc58c6769 100644
--- a/source/blender/blenlib/BLI_single_producer_chunk_consumer.hh
+++ b/source/blender/blenlib/BLI_single_producer_chunk_consumer.hh
@@ -35,7 +35,7 @@
 
 namespace blender {
 
-template<typename T, typename Allocator = GuardedAllocator>
+template<typename T, typename Allocator = GuardedAllocator, typename UserData = void>
 class SingleProducerChunkConsumerQueue {
  private:
   struct Chunk {
@@ -69,6 +69,9 @@ class SingleProducerChunkConsumerQueue {
      * This is modified by the append-operation and not accessed by the consume-operation.
      */
     T *end = nullptr;
+
+    using RealUserData = std::conditional_t<std::is_void_v<UserData>, char, UserData>;
+    RealUserData user_data;
   };
 
   struct SharedChunkView {
@@ -122,6 +125,11 @@ class SingleProducerChunkConsumerQueue {
     return new (current_->end) T(std::forward<Args>(args)...);
   }
 
+  UserData *user_data_for_current_append()
+  {
+    return &current_->user_data;
+  }
+
   /**
    * Tell the queue that the element has been constructed and is ready to be committed.
    * Once it is committed, the next consumer can read it.
diff --git a/source/blender/blenlib/intern/profile.cc b/source/blender/blenlib/intern/profile.cc
index c8ff6130729..13ee5274c0a 100644
--- a/source/blender/blenlib/intern/profile.cc
+++ b/source/blender/blenlib/intern/profile.cc
@@ -18,6 +18,7 @@
 #include <mutex>
 
 #include "BLI_function_ref.hh"
+#include "BLI_linear_allocator.hh"
 #include "BLI_profile.hh"
 #include "BLI_profile_manage.hh"
 #include "BLI_single_producer_chunk_consumer.hh"
@@ -61,7 +62,9 @@ static std::shared_ptr<ProfileRegistry> &ensure_registry()
   return registry;
 }
 
-template<typename T> using ProfileDataQueue = SingleProducerChunkConsumerQueue<T, RawAllocator>;
+template<typename T>
+using ProfileDataQueue =
+    SingleProducerChunkConsumerQueue<T, RawAllocator, LinearAllocator<RawAllocator>>;
 
 struct ThreadLocalProfileData {
   ThreadLocalProfileData()
@@ -168,9 +171,12 @@ static void profile_task_begin(BLI_ProfileTask *task, const char *name, uint64_t
   task->id = id;
 
   ProfileTaskBegin *task_begin = local_data.queue_begins.prepare_append();
+  LinearAllocator<RawAllocator> *allocator =
+      local_data.queue_begins.user_data_for_current_append();
+  StringRefNull name_copy = allocator->copy_string(name);
 
   task_begin->id = id;
-  task_begin->name = name;
+  task_begin->name = name_copy.c_str();
   task_begin->parent_id = parent_id;
   task_begin->thread_id = local_data.thread_id;
   task_begin->time = Clock::now();



More information about the Bf-blender-cvs mailing list