展示优化
This commit is contained in:
@@ -11,24 +11,24 @@
|
||||
namespace renderive {
|
||||
struct Render_Executor_Metrics;
|
||||
|
||||
struct Frame_Task_Counters {
|
||||
std::atomic_uint32_t task_count{0};
|
||||
std::atomic_uint32_t active_count{0};
|
||||
std::atomic_uint32_t peak_parallelism{0};
|
||||
std::atomic_uint64_t task_duration_total_ns{0};
|
||||
struct Frame_Business_Task_Counters {
|
||||
std::atomic_uint32_t business_task_count{0};
|
||||
std::atomic_uint32_t active_business_task_count{0};
|
||||
std::atomic_uint32_t business_task_peak_parallelism{0};
|
||||
std::atomic_uint64_t business_task_duration_total_ns{0};
|
||||
};
|
||||
|
||||
struct Taskflow_Graph_Impl {
|
||||
Taskflow_Graph_Impl(
|
||||
tf::Taskflow& taskflow,
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics,
|
||||
std::shared_ptr<Frame_Task_Counters> frame_counters)
|
||||
std::shared_ptr<Frame_Business_Task_Counters> frame_counters)
|
||||
: taskflow(taskflow),
|
||||
metrics(std::move(metrics)),
|
||||
frame_counters(std::move(frame_counters)) {}
|
||||
tf::Taskflow& taskflow;
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics;
|
||||
std::shared_ptr<Frame_Task_Counters> frame_counters;
|
||||
std::shared_ptr<Frame_Business_Task_Counters> frame_counters;
|
||||
std::vector<tf::Task> tasks;
|
||||
};
|
||||
|
||||
@@ -36,13 +36,13 @@ struct Taskflow_Subflow_Impl {
|
||||
Taskflow_Subflow_Impl(
|
||||
tf::Subflow& subflow,
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics,
|
||||
std::shared_ptr<Frame_Task_Counters> frame_counters)
|
||||
std::shared_ptr<Frame_Business_Task_Counters> frame_counters)
|
||||
: subflow(subflow),
|
||||
metrics(std::move(metrics)),
|
||||
frame_counters(std::move(frame_counters)) {}
|
||||
tf::Subflow& subflow;
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics;
|
||||
std::shared_ptr<Frame_Task_Counters> frame_counters;
|
||||
std::shared_ptr<Frame_Business_Task_Counters> frame_counters;
|
||||
std::vector<tf::Task> tasks;
|
||||
};
|
||||
|
||||
@@ -51,16 +51,18 @@ struct Render_Executor_Metrics {
|
||||
std::atomic<std::size_t> active_workers{0};
|
||||
std::atomic<std::size_t> active_frame_jobs{0};
|
||||
std::atomic<std::size_t> queued_frame_jobs{0};
|
||||
std::atomic<std::uint64_t> submitted_tasks{0};
|
||||
std::atomic<std::uint64_t> started_tasks{0};
|
||||
std::atomic<std::uint64_t> completed_tasks{0};
|
||||
std::atomic<std::uint64_t> submitted_topologies{0};
|
||||
std::atomic<std::uint64_t> started_topologies{0};
|
||||
std::atomic<std::uint64_t> completed_topologies{0};
|
||||
std::atomic<std::uint64_t> started_task_nodes{0};
|
||||
std::atomic<std::uint64_t> completed_task_nodes{0};
|
||||
std::atomic<std::uint64_t> rejected_frame_jobs{0};
|
||||
std::atomic<std::uint64_t> dropped_frame_attempts{0};
|
||||
std::atomic<std::uint64_t> peak_concurrency{0};
|
||||
std::atomic<std::uint64_t> queue_wait_total_ns{0};
|
||||
std::atomic<std::uint64_t> queue_wait_max_ns{0};
|
||||
std::atomic<std::uint64_t> task_duration_total_ns{0};
|
||||
std::atomic<std::uint64_t> task_duration_max_ns{0};
|
||||
std::atomic<std::uint64_t> topology_queue_wait_total_ns{0};
|
||||
std::atomic<std::uint64_t> topology_queue_wait_max_ns{0};
|
||||
std::atomic<std::uint64_t> task_node_duration_total_ns{0};
|
||||
std::atomic<std::uint64_t> task_node_duration_max_ns{0};
|
||||
std::atomic<std::uint64_t> curve_tasks{0};
|
||||
std::atomic<std::uint64_t> waterfall_tasks{0};
|
||||
std::atomic<std::uint64_t> primitive_tasks{0};
|
||||
@@ -94,30 +96,30 @@ void add_kind_count(Render_Executor_Metrics& metrics, Render_Task_Kind kind) {
|
||||
}
|
||||
}
|
||||
|
||||
void begin_business_task(Render_Executor_Metrics* metrics, Frame_Task_Counters* counters, Render_Task_Kind kind) {
|
||||
void begin_business_task(Render_Executor_Metrics* metrics, Frame_Business_Task_Counters* counters, Render_Task_Kind kind) {
|
||||
if (metrics)
|
||||
add_kind_count(*metrics, kind);
|
||||
if (!counters)
|
||||
return;
|
||||
counters->task_count.fetch_add(1, std::memory_order_relaxed);
|
||||
std::uint32_t active = counters->active_count.fetch_add(1, std::memory_order_acq_rel) + 1;
|
||||
std::uint32_t peak = counters->peak_parallelism.load(std::memory_order_acquire);
|
||||
while (peak < active && !counters->peak_parallelism.compare_exchange_weak(peak, active, std::memory_order_acq_rel, std::memory_order_acquire)) {}
|
||||
counters->business_task_count.fetch_add(1, std::memory_order_relaxed);
|
||||
std::uint32_t active = counters->active_business_task_count.fetch_add(1, std::memory_order_acq_rel) + 1;
|
||||
std::uint32_t peak = counters->business_task_peak_parallelism.load(std::memory_order_acquire);
|
||||
while (peak < active && !counters->business_task_peak_parallelism.compare_exchange_weak(peak, active, std::memory_order_acq_rel, std::memory_order_acquire)) {}
|
||||
}
|
||||
|
||||
void end_business_task(Frame_Task_Counters* counters, std::uint64_t begin_ns) {
|
||||
void end_business_task(Frame_Business_Task_Counters* counters, std::uint64_t begin_ns) {
|
||||
if (!counters)
|
||||
return;
|
||||
std::uint64_t end_ns = steady_now_ns();
|
||||
counters->task_duration_total_ns.fetch_add(end_ns > begin_ns ? end_ns - begin_ns : 0, std::memory_order_relaxed);
|
||||
counters->active_count.fetch_sub(1, std::memory_order_acq_rel);
|
||||
counters->business_task_duration_total_ns.fetch_add(end_ns > begin_ns ? end_ns - begin_ns : 0, std::memory_order_relaxed);
|
||||
counters->active_business_task_count.fetch_sub(1, std::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
Task wrap_business_task(
|
||||
Render_Task_Kind kind,
|
||||
Task work,
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics,
|
||||
std::shared_ptr<Frame_Task_Counters> counters) {
|
||||
std::shared_ptr<Frame_Business_Task_Counters> counters) {
|
||||
return Task([kind, work = std::move(work), metrics = std::move(metrics), counters = std::move(counters)]() mutable {
|
||||
std::uint64_t begin_ns = steady_now_ns();
|
||||
begin_business_task(metrics.get(), counters.get(), kind);
|
||||
@@ -221,7 +223,7 @@ public:
|
||||
if (worker_id < worker_entry_ns.size())
|
||||
worker_entry_ns[worker_id] = steady_now_ns();
|
||||
std::size_t active = metrics->active_workers.fetch_add(1, std::memory_order_acq_rel) + 1;
|
||||
metrics->started_tasks.fetch_add(1, std::memory_order_relaxed);
|
||||
metrics->started_task_nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
update_peak(metrics->peak_concurrency, static_cast<std::uint64_t>(active));
|
||||
}
|
||||
|
||||
@@ -233,10 +235,10 @@ public:
|
||||
std::uint64_t begin_ns = worker_entry_ns[worker_id];
|
||||
std::uint64_t end_ns = steady_now_ns();
|
||||
std::uint64_t duration_ns = end_ns > begin_ns ? end_ns - begin_ns : 0;
|
||||
metrics->task_duration_total_ns.fetch_add(duration_ns, std::memory_order_relaxed);
|
||||
update_peak(metrics->task_duration_max_ns, duration_ns);
|
||||
metrics->task_node_duration_total_ns.fetch_add(duration_ns, std::memory_order_relaxed);
|
||||
update_peak(metrics->task_node_duration_max_ns, duration_ns);
|
||||
}
|
||||
metrics->completed_tasks.fetch_add(1, std::memory_order_relaxed);
|
||||
metrics->completed_task_nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
metrics->active_workers.fetch_sub(1, std::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
@@ -246,7 +248,7 @@ private:
|
||||
};
|
||||
|
||||
class Render_Executor_Private {
|
||||
struct Task_Run_Record {
|
||||
struct Topology_Run_Record {
|
||||
std::uint64_t begin_ns{};
|
||||
std::uint64_t queue_wait_ns{};
|
||||
};
|
||||
@@ -282,11 +284,13 @@ public:
|
||||
}
|
||||
|
||||
Render_Executor_Snapshot snapshot() const {
|
||||
std::uint64_t submitted = metrics->submitted_tasks.load(std::memory_order_acquire);
|
||||
std::uint64_t completed = metrics->completed_tasks.load(std::memory_order_acquire);
|
||||
std::uint64_t started = metrics->started_tasks.load(std::memory_order_acquire);
|
||||
std::uint64_t queue_total = metrics->queue_wait_total_ns.load(std::memory_order_acquire);
|
||||
std::uint64_t duration_total = metrics->task_duration_total_ns.load(std::memory_order_acquire);
|
||||
std::uint64_t submitted_topologies = metrics->submitted_topologies.load(std::memory_order_acquire);
|
||||
std::uint64_t started_topologies = metrics->started_topologies.load(std::memory_order_acquire);
|
||||
std::uint64_t completed_topologies = metrics->completed_topologies.load(std::memory_order_acquire);
|
||||
std::uint64_t completed_task_nodes = metrics->completed_task_nodes.load(std::memory_order_acquire);
|
||||
std::uint64_t started_task_nodes = metrics->started_task_nodes.load(std::memory_order_acquire);
|
||||
std::uint64_t queue_total = metrics->topology_queue_wait_total_ns.load(std::memory_order_acquire);
|
||||
std::uint64_t duration_total = metrics->task_node_duration_total_ns.load(std::memory_order_acquire);
|
||||
std::size_t active = metrics->active_workers.load(std::memory_order_acquire);
|
||||
std::size_t workers = metrics->worker_count;
|
||||
return {
|
||||
@@ -295,16 +299,18 @@ public:
|
||||
workers > active ? workers - active : 0,
|
||||
metrics->active_frame_jobs.load(std::memory_order_acquire),
|
||||
metrics->queued_frame_jobs.load(std::memory_order_acquire),
|
||||
submitted,
|
||||
started,
|
||||
completed,
|
||||
submitted_topologies,
|
||||
started_topologies,
|
||||
completed_topologies,
|
||||
started_task_nodes,
|
||||
completed_task_nodes,
|
||||
metrics->rejected_frame_jobs.load(std::memory_order_acquire),
|
||||
metrics->dropped_frame_attempts.load(std::memory_order_acquire),
|
||||
metrics->peak_concurrency.load(std::memory_order_acquire),
|
||||
submitted ? queue_total / submitted : 0,
|
||||
metrics->queue_wait_max_ns.load(std::memory_order_acquire),
|
||||
completed ? duration_total / completed : 0,
|
||||
metrics->task_duration_max_ns.load(std::memory_order_acquire),
|
||||
started_topologies ? queue_total / started_topologies : 0,
|
||||
metrics->topology_queue_wait_max_ns.load(std::memory_order_acquire),
|
||||
completed_task_nodes ? duration_total / completed_task_nodes : 0,
|
||||
metrics->task_node_duration_max_ns.load(std::memory_order_acquire),
|
||||
metrics->curve_tasks.load(std::memory_order_acquire),
|
||||
metrics->waterfall_tasks.load(std::memory_order_acquire),
|
||||
metrics->primitive_tasks.load(std::memory_order_acquire),
|
||||
@@ -319,7 +325,7 @@ public:
|
||||
|
||||
private:
|
||||
void record_submission(Render_Executor_Task& task) {
|
||||
metrics->submitted_tasks.fetch_add(1, std::memory_order_relaxed);
|
||||
metrics->submitted_topologies.fetch_add(1, std::memory_order_relaxed);
|
||||
if (task.frame_job)
|
||||
metrics->queued_frame_jobs.fetch_add(1, std::memory_order_relaxed);
|
||||
if (task.frame_stat)
|
||||
@@ -329,8 +335,8 @@ private:
|
||||
void submit_to_executor(Render_Executor_Task task, std::uint64_t enqueue_ns) {
|
||||
auto task_ptr = std::make_shared<Render_Executor_Task>(std::move(task));
|
||||
auto completion = std::make_shared<Task>(std::move(task_ptr->completion));
|
||||
auto run_record = std::make_shared<Task_Run_Record>();
|
||||
auto frame_counters = std::make_shared<Frame_Task_Counters>();
|
||||
auto run_record = std::make_shared<Topology_Run_Record>();
|
||||
auto frame_counters = std::make_shared<Frame_Business_Task_Counters>();
|
||||
auto topology = std::make_shared<tf::Taskflow>();
|
||||
auto entry = topology->emplace([this, enqueue_ns, task_ptr, run_record]() mutable {
|
||||
Render_Executor_Task& task = *task_ptr;
|
||||
@@ -338,8 +344,9 @@ private:
|
||||
run_record->begin_ns = begin_ns;
|
||||
std::uint64_t queue_wait_ns = begin_ns > enqueue_ns ? begin_ns - enqueue_ns : 0;
|
||||
run_record->queue_wait_ns = queue_wait_ns;
|
||||
metrics->queue_wait_total_ns.fetch_add(queue_wait_ns, std::memory_order_relaxed);
|
||||
update_peak(metrics->queue_wait_max_ns, queue_wait_ns);
|
||||
metrics->started_topologies.fetch_add(1, std::memory_order_relaxed);
|
||||
metrics->topology_queue_wait_total_ns.fetch_add(queue_wait_ns, std::memory_order_relaxed);
|
||||
update_peak(metrics->topology_queue_wait_max_ns, queue_wait_ns);
|
||||
if (task.frame_job) {
|
||||
metrics->queued_frame_jobs.fetch_sub(1, std::memory_order_relaxed);
|
||||
metrics->active_frame_jobs.fetch_add(1, std::memory_order_relaxed);
|
||||
@@ -353,19 +360,19 @@ private:
|
||||
std::uint64_t run_ns = end_ns > begin_ns ? end_ns - begin_ns : 0;
|
||||
if (task.frame_stat) {
|
||||
Frame_Worker_Stats& stat = *task.frame_stat;
|
||||
std::uint32_t task_count = frame_counters ? frame_counters->task_count.load(std::memory_order_acquire) : 0;
|
||||
std::uint32_t peak_parallelism = frame_counters ? frame_counters->peak_parallelism.load(std::memory_order_acquire) : 0;
|
||||
std::uint64_t task_duration_total_ns = frame_counters ? frame_counters->task_duration_total_ns.load(std::memory_order_acquire) : 0;
|
||||
stat.task_count += task_count;
|
||||
stat.peak_parallelism = std::max(stat.peak_parallelism, peak_parallelism);
|
||||
stat.queue_wait_total_ns += queue_wait_ns;
|
||||
stat.queue_wait_max_ns = std::max(stat.queue_wait_max_ns, queue_wait_ns);
|
||||
stat.worker_run_total_ns += task_duration_total_ns;
|
||||
stat.parallel_stage_wall_ns += run_ns;
|
||||
stat.executor_at_finish = snapshot();
|
||||
std::uint32_t business_task_count = frame_counters ? frame_counters->business_task_count.load(std::memory_order_acquire) : 0;
|
||||
std::uint32_t business_task_peak_parallelism = frame_counters ? frame_counters->business_task_peak_parallelism.load(std::memory_order_acquire) : 0;
|
||||
std::uint64_t business_task_duration_total_ns = frame_counters ? frame_counters->business_task_duration_total_ns.load(std::memory_order_acquire) : 0;
|
||||
stat.business_task_count += business_task_count;
|
||||
stat.business_task_peak_parallelism = std::max(stat.business_task_peak_parallelism, business_task_peak_parallelism);
|
||||
stat.topology_queue_wait_total_ns += queue_wait_ns;
|
||||
stat.topology_queue_wait_max_ns = std::max(stat.topology_queue_wait_max_ns, queue_wait_ns);
|
||||
stat.business_task_run_total_ns += business_task_duration_total_ns;
|
||||
stat.topology_run_total_ns += run_ns;
|
||||
}
|
||||
if (task.frame_job)
|
||||
metrics->active_frame_jobs.fetch_sub(1, std::memory_order_relaxed);
|
||||
metrics->completed_topologies.fetch_add(1, std::memory_order_relaxed);
|
||||
});
|
||||
if (task_ptr->build_graph) {
|
||||
Taskflow_Graph_Impl graph_impl(*topology, metrics, frame_counters);
|
||||
@@ -384,7 +391,8 @@ private:
|
||||
work.precede(exit);
|
||||
}
|
||||
executor.run(*topology, [this, topology, completion, task_ptr]() mutable {
|
||||
(void)this;
|
||||
if (task_ptr->frame_stat)
|
||||
task_ptr->frame_stat->executor_at_finish = snapshot();
|
||||
if (completion && *completion)
|
||||
(*completion)();
|
||||
});
|
||||
@@ -396,7 +404,7 @@ private:
|
||||
else
|
||||
metrics->dropped_frame_attempts.fetch_add(1, std::memory_order_relaxed);
|
||||
if (task.frame_stat)
|
||||
task.frame_stat->rejected_task_count++;
|
||||
task.frame_stat->rejected_topology_count++;
|
||||
}
|
||||
|
||||
std::shared_ptr<Render_Executor_Metrics> metrics;
|
||||
|
||||
Reference in New Issue
Block a user