Skip to content

Commit a8ffbbd

Browse files
committed
Using custom TopoQueue implementation, ~ twice as fast.
1 parent a52664f commit a8ffbbd

3 files changed

Lines changed: 37 additions & 34 deletions

File tree

include/react/common/TopoQueue.h

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,43 @@ template <typename T>
2424
class TopoQueue
2525
{
2626
public:
27-
static bool LevelOrderOp(const T* lhs, const T* rhs)
28-
{
29-
return lhs->Level > rhs->Level;
30-
}
27+
using DataT = std::vector<T*>;
3128

3229
void Push(T* node)
3330
{
3431
data_.push_back(node);
35-
std::push_heap(data_.begin(), data_.end(), LevelOrderOp);
3632
}
3733

38-
void Pop()
34+
bool FetchNext()
3935
{
40-
std::pop_heap(data_.begin(), data_.end(), LevelOrderOp);
41-
data_.pop_back();
42-
}
36+
next_.clear();
4337

44-
T* Top() const
45-
{
46-
return data_.front();
47-
}
38+
minLevel_ = INT_MAX;
39+
for (const auto& e : data_)
40+
if (minLevel_ > e->Level)
41+
minLevel_ = e->Level;
4842

49-
bool Empty() const
50-
{
51-
return data_.empty();
52-
}
43+
auto p = std::partition(data_.begin(), data_.end(), CompFunctor{ minLevel_ });
5344

54-
void Invalidate()
55-
{
56-
std::make_heap(data_.begin(), data_.end(), LevelOrderOp);
45+
next_.insert(next_.end(), p, data_.end());
46+
data_.resize(std::distance(data_.begin(), p));
47+
48+
return !next_.empty();
5749
}
5850

51+
const DataT& NextNodes() const { return next_; }
52+
5953
private:
60-
std::vector<T*> data_;
54+
struct CompFunctor
55+
{
56+
CompFunctor(int level) : Level{ level } {}
57+
bool operator()(T* x) { return x->Level != Level; }
58+
const int Level;
59+
};
60+
61+
DataT next_;
62+
DataT data_;
63+
int minLevel_ = INT_MAX;
6164
};
6265

6366
///////////////////////////////////////////////////////////////////////////////////////////////////

include/react/propagation/TopoSortEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ParNode : public IReactiveNode
6868
int Level = 0;
6969
int NewLevel = 0;
7070
atomic<bool> Collected = false;
71-
int Weight = 1;
71+
uint Weight = 1;
7272

7373
NodeVector<ParNode> Successors;
7474
InvalidateMutexT InvalidateMutex;

src/react/propagation/TopoSortEngine.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,21 @@ template class EngineBase<ParNode,DefaultQueueableTurn<ExclusiveTurn>>;
6060
template <typename TTurn>
6161
void SeqEngineBase<TTurn>::OnTurnPropagate(TTurn& turn)
6262
{
63-
while (!scheduledNodes_.Empty())
63+
while (scheduledNodes_.FetchNext())
6464
{
65-
auto node = scheduledNodes_.Top();
66-
scheduledNodes_.Pop();
67-
68-
if (node->Level < node->NewLevel)
65+
for (auto* curNode : scheduledNodes_.NextNodes())
6966
{
70-
node->Level = node->NewLevel;
71-
invalidateSuccessors(*node);
72-
scheduledNodes_.Push(node);
73-
continue;
74-
}
67+
if (curNode->Level < curNode->NewLevel)
68+
{
69+
curNode->Level = curNode->NewLevel;
70+
invalidateSuccessors(*curNode);
71+
scheduledNodes_.Push(curNode);
72+
continue;
73+
}
7574

76-
node->Queued = false;
77-
node->Tick(&turn);
75+
curNode->Queued = false;
76+
curNode->Tick(&turn);
77+
}
7878
}
7979
}
8080

0 commit comments

Comments
 (0)