[turbofan] Instruction scheduler: keep ready nodes list sorted by latency.
This significantly speed-up the instruction scheduler when the ready list contains a large number of instruction. R=jarin@chromium.org, bmeurer@chromium.org Review-Url: https://codereview.chromium.org/2281523002 Cr-Commit-Position: refs/heads/master@{#38919}
This commit is contained in:
parent
51c186dd98
commit
f93ca29cac
@ -11,11 +11,16 @@ namespace v8 {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
|
||||||
// Compare the two nodes and return true if node1 is a better candidate than
|
void InstructionScheduler::SchedulingQueueBase::AddNode(
|
||||||
// node2 (i.e. node1 should be scheduled before node2).
|
ScheduleGraphNode* node) {
|
||||||
bool InstructionScheduler::CriticalPathFirstQueue::CompareNodes(
|
// We keep the ready list sorted by total latency so that we can quickly find
|
||||||
ScheduleGraphNode *node1, ScheduleGraphNode *node2) const {
|
// the next best candidate to schedule.
|
||||||
return node1->total_latency() > node2->total_latency();
|
auto it = nodes_.begin();
|
||||||
|
while ((it != nodes_.end()) &&
|
||||||
|
((*it)->total_latency() > node->total_latency())) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
nodes_.insert(it, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -24,12 +29,10 @@ InstructionScheduler::CriticalPathFirstQueue::PopBestCandidate(int cycle) {
|
|||||||
DCHECK(!IsEmpty());
|
DCHECK(!IsEmpty());
|
||||||
auto candidate = nodes_.end();
|
auto candidate = nodes_.end();
|
||||||
for (auto iterator = nodes_.begin(); iterator != nodes_.end(); ++iterator) {
|
for (auto iterator = nodes_.begin(); iterator != nodes_.end(); ++iterator) {
|
||||||
// We only consider instructions that have all their operands ready and
|
// We only consider instructions that have all their operands ready.
|
||||||
// we try to schedule the critical path first.
|
|
||||||
if (cycle >= (*iterator)->start_cycle()) {
|
if (cycle >= (*iterator)->start_cycle()) {
|
||||||
if ((candidate == nodes_.end()) || CompareNodes(*iterator, *candidate)) {
|
candidate = iterator;
|
||||||
candidate = iterator;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +101,7 @@ class InstructionScheduler final : public ZoneObject {
|
|||||||
nodes_(scheduler->zone()) {
|
nodes_(scheduler->zone()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNode(ScheduleGraphNode* node) {
|
void AddNode(ScheduleGraphNode* node);
|
||||||
nodes_.push_back(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEmpty() const {
|
bool IsEmpty() const {
|
||||||
return nodes_.empty();
|
return nodes_.empty();
|
||||||
@ -125,11 +123,6 @@ class InstructionScheduler final : public ZoneObject {
|
|||||||
// Look for the best candidate to schedule, remove it from the queue and
|
// Look for the best candidate to schedule, remove it from the queue and
|
||||||
// return it.
|
// return it.
|
||||||
ScheduleGraphNode* PopBestCandidate(int cycle);
|
ScheduleGraphNode* PopBestCandidate(int cycle);
|
||||||
|
|
||||||
private:
|
|
||||||
// Compare the two nodes and return true if node1 is a better candidate than
|
|
||||||
// node2 (i.e. node1 should be scheduled before node2).
|
|
||||||
bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A queue which pop a random node from the queue to perform stress tests on
|
// A queue which pop a random node from the queue to perform stress tests on
|
||||||
|
Loading…
Reference in New Issue
Block a user