[Bf-blender-cvs] [05e6466ed0e] profiler-editor: add basic profile recording

Jacques Lucke noreply at git.blender.org
Thu Apr 29 11:30:46 CEST 2021


Commit: 05e6466ed0e320ed05f796a8f3265d2228e64f30
Author: Jacques Lucke
Date:   Mon Apr 26 17:50:42 2021 +0200
Branches: profiler-editor
https://developer.blender.org/rB05e6466ed0e320ed05f796a8f3265d2228e64f30

add basic profile recording

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

M	source/blender/blenlib/BLI_profile_manage.hh
M	source/blender/blenlib/BLI_stack.hh
M	source/blender/blenlib/intern/profile.cc

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

diff --git a/source/blender/blenlib/BLI_profile_manage.hh b/source/blender/blenlib/BLI_profile_manage.hh
index 650009850af..3028efeb36c 100644
--- a/source/blender/blenlib/BLI_profile_manage.hh
+++ b/source/blender/blenlib/BLI_profile_manage.hh
@@ -29,6 +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;
   TimePoint time;
   uint64_t id;
@@ -42,8 +43,8 @@ struct ProfileTaskEnd {
 };
 
 struct RecordedProfile {
-  Vector<ProfileTaskBegin> task_begins;
-  Vector<ProfileTaskEnd> task_ends;
+  RawVector<ProfileTaskBegin> task_begins;
+  RawVector<ProfileTaskEnd> task_ends;
 };
 
 class ProfileListener {
diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh
index d66316a95d9..8f3a35bc463 100644
--- a/source/blender/blenlib/BLI_stack.hh
+++ b/source/blender/blenlib/BLI_stack.hh
@@ -287,6 +287,14 @@ class Stack {
     return *(top_ - 1);
   }
 
+  const T &peek_default(const T &default_value) const
+  {
+    if (size_ > 0) {
+      return this->peek();
+    }
+    return default_value;
+  }
+
   /**
    * Add multiple elements to the stack. The values are pushed in the order they are in the array.
    * This method is more efficient than pushing multiple elements individually and might cause less
diff --git a/source/blender/blenlib/intern/profile.cc b/source/blender/blenlib/intern/profile.cc
index f248f05344b..ad42435ec4d 100644
--- a/source/blender/blenlib/intern/profile.cc
+++ b/source/blender/blenlib/intern/profile.cc
@@ -14,10 +14,27 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include <atomic>
 #include <mutex>
 
 #include "BLI_profile.hh"
 #include "BLI_profile_manage.hh"
+#include "BLI_stack.hh"
+
+using namespace blender;
+using namespace blender::profile;
+
+static uint64_t get_unique_session_id()
+{
+  /* TODO: Allow getting ids without synchronizing threads for every id. */
+  static std::atomic<uint64_t> id = 1;
+  return id++;
+}
+
+static RawVector<ProfileTaskBegin> recorded_task_begins;
+static RawVector<ProfileTaskEnd> recorded_task_ends;
+static thread_local RawStack<uint64_t> threadlocal_id_stack;
+static thread_local uint64_t threadlocal_thread_id = get_unique_session_id();
 
 namespace blender::profile {
 
@@ -31,12 +48,13 @@ static void stop_profiling()
   bli_profiling_is_enabled = false;
 }
 
-static std::mutex listeners_mutex;
+/* TODO: Need to reduce threading overhead, but this works fine for now. */
+static std::mutex profile_mutex;
 static RawVector<ProfileListener *> listeners;
 
 ProfileListener::ProfileListener()
 {
-  std::lock_guard lock{listeners_mutex};
+  std::lock_guard lock{profile_mutex};
   listeners.append(this);
   if (listeners.size() == 1) {
     start_profiling();
@@ -45,7 +63,7 @@ ProfileListener::ProfileListener()
 
 ProfileListener::~ProfileListener()
 {
-  std::lock_guard lock{listeners_mutex};
+  std::lock_guard lock{profile_mutex};
   listeners.remove_first_occurrence_and_reorder(this);
   if (listeners.is_empty()) {
     stop_profiling();
@@ -54,8 +72,10 @@ ProfileListener::~ProfileListener()
 
 void ProfileListener::flush_to_all()
 {
-  std::lock_guard lock{listeners_mutex};
+  std::lock_guard lock{profile_mutex};
   RecordedProfile recorded_profile;
+  recorded_profile.task_begins = std::move(recorded_task_begins);
+  recorded_profile.task_ends = std::move(recorded_task_ends);
 
   for (ProfileListener *listener : listeners) {
     listener->handle(recorded_profile);
@@ -64,21 +84,44 @@ void ProfileListener::flush_to_all()
 
 }  // namespace blender::profile
 
-using namespace blender::profile;
-
 void _bli_profile_task_begin(BLI_ProfileTask *task, const char *name)
 {
-  UNUSED_VARS(task, name);
+  ProfileTaskBegin task_begin;
+  task_begin.id = get_unique_session_id();
+  task_begin.name = name;
+  task_begin.parent_id = threadlocal_id_stack.peek_default(0);
+  task_begin.thread_id = threadlocal_thread_id;
+  task_begin.time = Clock::now();
+
+  task->id = task_begin.id;
+
+  std::scoped_lock lock{profile_mutex};
+  recorded_task_begins.append(task_begin);
 }
 
 void _bli_profile_task_begin_subtask(BLI_ProfileTask *task,
                                      const char *name,
                                      const BLI_ProfileTask *parent_task)
 {
-  UNUSED_VARS(task, name, parent_task);
+  ProfileTaskBegin task_begin;
+  task_begin.id = get_unique_session_id();
+  task_begin.name = name;
+  task_begin.parent_id = parent_task->id;
+  task_begin.thread_id = threadlocal_thread_id;
+  task_begin.time = Clock::now();
+
+  task->id = task_begin.id;
+
+  std::scoped_lock lock{profile_mutex};
+  recorded_task_begins.append(task_begin);
 }
 
 void _bli_profile_task_end(BLI_ProfileTask *task)
 {
-  UNUSED_VARS(task);
+  ProfileTaskEnd task_end;
+  task_end.begin_id = task->id;
+  task_end.time = Clock::now();
+
+  std::scoped_lock lock{profile_mutex};
+  recorded_task_ends.append(task_end);
 }



More information about the Bf-blender-cvs mailing list