Commit 651b0c34 authored by Victor Miura's avatar Victor Miura Committed by Commit Bot

Reland "gpu scheduler: Compute stream priorities based on priority of waiters."

This is a reland of 56eadad0
Original change's description:
> gpu scheduler: Compute stream priorities based on priority of waiters.
> 
> Previously, a stream tracked all of it's fences that had waiting streams
> in 'release_fences'.  If 'release_fences' was non-empty, the stream's
> priority got bumped up to High.  This means a stream with Normal priority
> waiting on Low priority stream could bump that stream up to High priority.
> 
> This change removes that tracking, and instead keeps count of the number
> of waiting streams at each StreamPriority.  The highest priority with non-
> zero count becomes the stream's priority.
> 
> When a stream changes priority, it recursively propagates it's new priority
> to all streams it's waiting on.
> 
> BUG=781585
> 
> Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
> Change-Id: I1fc96f6ca065a8e1f83ddaa61ae4f9725c324bcb
> Reviewed-on: https://chromium-review.googlesource.com/754415
> Commit-Queue: Victor Miura <vmiura@chromium.org>
> Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
> Reviewed-by: Antoine Labour <piman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#515097}

Bug: 781585
Change-Id: I67055fe2887a8ffcc8032af32ab221a3d66bedac
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Reviewed-on: https://chromium-review.googlesource.com/762145
Commit-Queue: Victor Miura <vmiura@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517702}
parent 10686d89
This diff is collapsed.
...@@ -9,7 +9,10 @@ ...@@ -9,7 +9,10 @@
#include <vector> #include <vector>
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
...@@ -88,7 +91,6 @@ class GPU_EXPORT Scheduler { ...@@ -88,7 +91,6 @@ class GPU_EXPORT Scheduler {
bool ShouldYield(SequenceId sequence_id); bool ShouldYield(SequenceId sequence_id);
private: private:
class Sequence;
struct SchedulingState { struct SchedulingState {
static bool Comparator(const SchedulingState& lhs, static bool Comparator(const SchedulingState& lhs,
...@@ -113,6 +115,162 @@ class GPU_EXPORT Scheduler { ...@@ -113,6 +115,162 @@ class GPU_EXPORT Scheduler {
uint32_t order_num = 0; uint32_t order_num = 0;
}; };
class GPU_EXPORT Sequence {
public:
Sequence(Scheduler* scheduler,
SequenceId sequence_id,
SchedulingPriority priority,
scoped_refptr<SyncPointOrderData> order_data);
~Sequence();
SequenceId sequence_id() const { return sequence_id_; }
const scoped_refptr<SyncPointOrderData>& order_data() const {
return order_data_;
}
bool enabled() const { return enabled_; }
bool scheduled() const { return running_state_ == SCHEDULED; }
bool running() const { return running_state_ == RUNNING; }
// The sequence is runnable if its enabled and has tasks which are not
// blocked by wait fences.
bool IsRunnable() const;
// Returns true if this sequence's scheduling state changed and it needs to
// be reinserted into the scheduling queue.
bool NeedsRescheduling() const;
// Returns true if this sequence should yield to another sequence. Uses the
// cached scheduling state for comparison.
bool ShouldYieldTo(const Sequence* other) const;
// Enables or disables the sequence.
void SetEnabled(bool enabled);
// Sets running state to SCHEDULED. Returns scheduling state for this
// sequence used for inserting in the scheduling queue.
SchedulingState SetScheduled();
// Update cached scheduling priority while running.
void UpdateRunningPriority();
// Returns the next order number and closure. Sets running state to RUNNING.
uint32_t BeginTask(base::OnceClosure* closure);
// Called after running the closure returned by BeginTask. Sets running
// state to IDLE.
void FinishTask();
// Enqueues a task in the sequence and returns the generated order number.
uint32_t ScheduleTask(base::OnceClosure closure);
// Continue running the current task with the given closure. Must be called
// in between |BeginTask| and |FinishTask|.
void ContinueTask(base::OnceClosure closure);
// Add a sync token fence that this sequence should wait on.
void AddWaitFence(const SyncToken& sync_token,
uint32_t order_num,
SequenceId release_sequence_id,
Sequence* release_sequence);
// Remove a waiting sync token fence.
void RemoveWaitFence(const SyncToken& sync_token,
uint32_t order_num,
SequenceId release_sequence_id);
void AddClientWait(CommandBufferId command_buffer_id);
void RemoveClientWait(CommandBufferId command_buffer_id);
SchedulingPriority current_priority() const { return current_priority_; }
private:
enum RunningState { IDLE, SCHEDULED, RUNNING };
struct Fence {
Fence(Fence&& other);
Fence(const SyncToken& sync_token,
uint32_t order_num,
SequenceId release_sequence_id);
~Fence();
Fence& operator=(Fence&& other);
SyncToken sync_token;
uint32_t order_num;
SequenceId release_sequence_id;
bool operator==(const Fence& other) const {
return std::tie(sync_token, order_num, release_sequence_id) ==
std::tie(other.sync_token, other.order_num, release_sequence_id);
}
};
struct Task {
Task(Task&& other);
Task(base::OnceClosure closure, uint32_t order_num);
~Task();
Task& operator=(Task&& other);
base::OnceClosure closure;
uint32_t order_num;
};
// Add a waiting priority.
void AddWaitingPriority(SchedulingPriority priority);
// Remove a waiting priority.
void RemoveWaitingPriority(SchedulingPriority priority);
// Change a waiting priority.
void ChangeWaitingPriority(SchedulingPriority old_priority,
SchedulingPriority new_priority);
// Re-compute current priority.
void UpdateSchedulingPriority();
// If the sequence is enabled. Sequences are disabled/enabled based on when
// the command buffer is descheduled/scheduled.
bool enabled_ = true;
RunningState running_state_ = IDLE;
// Cached scheduling state used for comparison with other sequences while
// running. Updated in |SetScheduled| and |UpdateRunningPriority|.
SchedulingState scheduling_state_;
Scheduler* const scheduler_;
const SequenceId sequence_id_;
const SchedulingPriority default_priority_;
SchedulingPriority current_priority_;
scoped_refptr<SyncPointOrderData> order_data_;
// Deque of tasks. Tasks are inserted at the back with increasing order
// number generated from SyncPointOrderData. If a running task needs to be
// continued, it is inserted at the front with the same order number.
base::circular_deque<Task> tasks_;
// List of fences that this sequence is waiting on. Fences are inserted in
// increasing order number but may be removed out of order. Tasks are
// blocked if there's a wait fence with order number less than or equal to
// the task's order number.
std::vector<Fence> wait_fences_;
// Counts of pending releases bucketed by scheduling priority.
int waiting_priority_counts_[static_cast<int>(SchedulingPriority::kLast) +
1] = {};
base::flat_set<CommandBufferId> client_waits_;
DISALLOW_COPY_AND_ASSIGN(Sequence);
};
void SyncTokenFenceReleased(const SyncToken& sync_token, void SyncTokenFenceReleased(const SyncToken& sync_token,
uint32_t order_num, uint32_t order_num,
SequenceId release_sequence_id, SequenceId release_sequence_id,
...@@ -151,6 +309,11 @@ class GPU_EXPORT Scheduler { ...@@ -151,6 +309,11 @@ class GPU_EXPORT Scheduler {
base::WeakPtrFactory<Scheduler> weak_factory_; base::WeakPtrFactory<Scheduler> weak_factory_;
private:
FRIEND_TEST_ALL_PREFIXES(SchedulerTest, StreamPriorities);
FRIEND_TEST_ALL_PREFIXES(SchedulerTest, StreamDestroyRemovesPriorities);
FRIEND_TEST_ALL_PREFIXES(SchedulerTest, StreamPriorityChangeWhileReleasing);
FRIEND_TEST_ALL_PREFIXES(SchedulerTest, CircularPriorities);
DISALLOW_COPY_AND_ASSIGN(Scheduler); DISALLOW_COPY_AND_ASSIGN(Scheduler);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment