Merge pull request #525 from YosysHQ/dave/router2-tweaks
router2: Improve thread safety
This commit is contained in:
commit
62dde576e0
@ -85,6 +85,8 @@ struct Router2
|
|||||||
bool unavailable = false;
|
bool unavailable = false;
|
||||||
// This wire has to be used for this net
|
// This wire has to be used for this net
|
||||||
int reserved_net = -1;
|
int reserved_net = -1;
|
||||||
|
// The notional location of the wire, to guarantee thread safety
|
||||||
|
int16_t x = 0, y = 0;
|
||||||
// Visit data
|
// Visit data
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -200,6 +202,11 @@ struct Router2
|
|||||||
if (bound->wires.at(wire).strength > STRENGTH_STRONG)
|
if (bound->wires.at(wire).strength > STRENGTH_STRONG)
|
||||||
pwd.unavailable = true;
|
pwd.unavailable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArcBounds wire_loc = ctx->getRouteBoundingBox(wire, wire);
|
||||||
|
pwd.x = (wire_loc.x0 + wire_loc.x1) / 2;
|
||||||
|
pwd.y = (wire_loc.y0 + wire_loc.y1) / 2;
|
||||||
|
|
||||||
wire_to_idx[wire] = int(flat_wires.size());
|
wire_to_idx[wire] = int(flat_wires.size());
|
||||||
flat_wires.push_back(pwd);
|
flat_wires.push_back(pwd);
|
||||||
}
|
}
|
||||||
@ -254,8 +261,18 @@ struct Router2
|
|||||||
std::queue<int> backwards_queue;
|
std::queue<int> backwards_queue;
|
||||||
|
|
||||||
std::vector<int> dirty_wires;
|
std::vector<int> dirty_wires;
|
||||||
|
|
||||||
|
// Thread bounding box
|
||||||
|
ArcBounds bb;
|
||||||
|
|
||||||
|
DeterministicRNG rng;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool thread_test_wire(ThreadContext &t, PerWireData &w)
|
||||||
|
{
|
||||||
|
return w.x >= t.bb.x0 && w.x <= t.bb.x1 && w.y >= t.bb.y0 && w.y <= t.bb.y1;
|
||||||
|
}
|
||||||
|
|
||||||
enum ArcRouteResult
|
enum ArcRouteResult
|
||||||
{
|
{
|
||||||
ARC_SUCCESS,
|
ARC_SUCCESS,
|
||||||
@ -530,6 +547,8 @@ struct Router2
|
|||||||
continue;
|
continue;
|
||||||
if (wd.bound_nets.size() > 1 || (wd.bound_nets.size() == 1 && !wd.bound_nets.count(net->udata)))
|
if (wd.bound_nets.size() > 1 || (wd.bound_nets.size() == 1 && !wd.bound_nets.count(net->udata)))
|
||||||
continue; // never allow congestion in backwards routing
|
continue; // never allow congestion in backwards routing
|
||||||
|
if (!thread_test_wire(t, wd))
|
||||||
|
continue; // thread safety issue
|
||||||
t.backwards_queue.push(next);
|
t.backwards_queue.push(next);
|
||||||
set_visited(t, next, uh, WireScore());
|
set_visited(t, next, uh, WireScore());
|
||||||
}
|
}
|
||||||
@ -615,6 +634,8 @@ struct Router2
|
|||||||
continue;
|
continue;
|
||||||
if (nwd.bound_nets.count(net->udata) && nwd.bound_nets.at(net->udata).second != dh)
|
if (nwd.bound_nets.count(net->udata) && nwd.bound_nets.at(net->udata).second != dh)
|
||||||
continue;
|
continue;
|
||||||
|
if (!thread_test_wire(t, nwd))
|
||||||
|
continue; // thread safety issue
|
||||||
WireScore next_score;
|
WireScore next_score;
|
||||||
next_score.cost = curr.score.cost + score_wire_for_arc(net, i, next, dh);
|
next_score.cost = curr.score.cost + score_wire_for_arc(net, i, next, dh);
|
||||||
next_score.delay =
|
next_score.delay =
|
||||||
@ -628,7 +649,7 @@ struct Router2
|
|||||||
next_score.togo_cost);
|
next_score.togo_cost);
|
||||||
#endif
|
#endif
|
||||||
// Add wire to queue if it meets criteria
|
// Add wire to queue if it meets criteria
|
||||||
t.queue.push(QueuedWire(next_idx, dh, ctx->getPipLocation(dh), next_score, ctx->rng()));
|
t.queue.push(QueuedWire(next_idx, dh, ctx->getPipLocation(dh), next_score, t.rng.rng()));
|
||||||
set_visited(t, next_idx, dh, next_score);
|
set_visited(t, next_idx, dh, next_score);
|
||||||
if (next == dst_wire) {
|
if (next == dst_wire) {
|
||||||
toexplore = std::min(toexplore, iter + 5);
|
toexplore = std::min(toexplore, iter + 5);
|
||||||
@ -948,6 +969,8 @@ struct Router2
|
|||||||
// Don't multithread if fewer than 200 nets (heuristic)
|
// Don't multithread if fewer than 200 nets (heuristic)
|
||||||
if (route_queue.size() < 200) {
|
if (route_queue.size() < 200) {
|
||||||
ThreadContext st;
|
ThreadContext st;
|
||||||
|
st.rng.rngseed(ctx->rng64());
|
||||||
|
st.bb = ArcBounds(0, 0, std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
|
||||||
for (size_t j = 0; j < route_queue.size(); j++) {
|
for (size_t j = 0; j < route_queue.size(); j++) {
|
||||||
route_net(st, nets_by_udata[route_queue[j]], false);
|
route_net(st, nets_by_udata[route_queue[j]], false);
|
||||||
}
|
}
|
||||||
@ -956,14 +979,32 @@ struct Router2
|
|||||||
const int Nq = 4, Nv = 2, Nh = 2;
|
const int Nq = 4, Nv = 2, Nh = 2;
|
||||||
const int N = Nq + Nv + Nh;
|
const int N = Nq + Nv + Nh;
|
||||||
std::vector<ThreadContext> tcs(N + 1);
|
std::vector<ThreadContext> tcs(N + 1);
|
||||||
|
for (auto &th : tcs) {
|
||||||
|
th.rng.rngseed(ctx->rng64());
|
||||||
|
}
|
||||||
|
int le_x = mid_x - cfg.bb_margin_x;
|
||||||
|
int rs_x = mid_x + cfg.bb_margin_x;
|
||||||
|
int le_y = mid_y - cfg.bb_margin_y;
|
||||||
|
int rs_y = mid_y + cfg.bb_margin_y;
|
||||||
|
// Set up thread bounding boxes
|
||||||
|
tcs.at(0).bb = ArcBounds(0, 0, mid_x, mid_y);
|
||||||
|
tcs.at(1).bb = ArcBounds(mid_x + 1, 0, std::numeric_limits<int>::max(), le_y);
|
||||||
|
tcs.at(2).bb = ArcBounds(0, mid_y + 1, mid_x, std::numeric_limits<int>::max());
|
||||||
|
tcs.at(3).bb =
|
||||||
|
ArcBounds(mid_x + 1, mid_y + 1, std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
tcs.at(4).bb = ArcBounds(0, 0, std::numeric_limits<int>::max(), mid_y);
|
||||||
|
tcs.at(5).bb = ArcBounds(0, mid_y + 1, std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
tcs.at(6).bb = ArcBounds(0, 0, mid_x, std::numeric_limits<int>::max());
|
||||||
|
tcs.at(7).bb = ArcBounds(mid_x + 1, 0, std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
tcs.at(8).bb = ArcBounds(0, 0, std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
|
||||||
|
|
||||||
for (auto n : route_queue) {
|
for (auto n : route_queue) {
|
||||||
auto &nd = nets.at(n);
|
auto &nd = nets.at(n);
|
||||||
auto ni = nets_by_udata.at(n);
|
auto ni = nets_by_udata.at(n);
|
||||||
int bin = N;
|
int bin = N;
|
||||||
int le_x = mid_x - cfg.bb_margin_x;
|
|
||||||
int rs_x = mid_x + cfg.bb_margin_x;
|
|
||||||
int le_y = mid_y - cfg.bb_margin_y;
|
|
||||||
int rs_y = mid_y + cfg.bb_margin_y;
|
|
||||||
// Quadrants
|
// Quadrants
|
||||||
if (nd.bb.x0 < le_x && nd.bb.x1 < le_x && nd.bb.y0 < le_y && nd.bb.y1 < le_y)
|
if (nd.bb.x0 < le_x && nd.bb.x1 < le_x && nd.bb.y0 < le_y && nd.bb.y1 < le_y)
|
||||||
bin = 0;
|
bin = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user