Skip to content

Commit 359f142

Browse files
committed
Split node ptc data away from core storage.
This enables 16-byte alignment (4 nodes per cache line). Signed-off-by: Keith Rothman <[email protected]>
1 parent 0b15b11 commit 359f142

File tree

4 files changed

+120
-33
lines changed

4 files changed

+120
-33
lines changed

vpr/src/route/rr_node.cpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,32 +105,19 @@ void t_rr_node::set_coordinates(short x1, short y1, short x2, short y2) {
105105
}
106106

107107
void t_rr_node::set_ptc_num(short new_ptc_num) {
108-
auto& node = storage_->get(id_);
109-
node.ptc_.pin_num = new_ptc_num; //TODO: eventually remove
108+
storage_->set_node_ptc_num(id_, new_ptc_num);
110109
}
111110

112111
void t_rr_node::set_pin_num(short new_pin_num) {
113-
if (type() != IPIN && type() != OPIN) {
114-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'pin_num' for non-IPIN/OPIN type '%s'", type_string());
115-
}
116-
auto& node = storage_->get(id_);
117-
node.ptc_.pin_num = new_pin_num;
112+
storage_->set_node_pin_num(id_, new_pin_num);
118113
}
119114

120115
void t_rr_node::set_track_num(short new_track_num) {
121-
if (type() != CHANX && type() != CHANY) {
122-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'track_num' for non-CHANX/CHANY type '%s'", type_string());
123-
}
124-
auto& node = storage_->get(id_);
125-
node.ptc_.track_num = new_track_num;
116+
storage_->set_node_track_num(id_, new_track_num);
126117
}
127118

128119
void t_rr_node::set_class_num(short new_class_num) {
129-
if (type() != SOURCE && type() != SINK) {
130-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'class_num' for non-SOURCE/SINK type '%s'", type_string());
131-
}
132-
auto& node = storage_->get(id_);
133-
node.ptc_.class_num = new_class_num;
120+
storage_->set_node_class_num(id_, new_class_num);
134121
}
135122

136123
void t_rr_node::set_cost_index(size_t new_cost_index) {

vpr/src/route/rr_node_impl.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,28 +126,19 @@ inline short t_rr_node::capacity() const {
126126
}
127127

128128
inline short t_rr_node::ptc_num() const {
129-
return storage_->get(id_).ptc_.pin_num;
129+
return storage_->node_ptc_num(id_);
130130
}
131131

132132
inline short t_rr_node::pin_num() const {
133-
if (type() != IPIN && type() != OPIN) {
134-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'pin_num' for non-IPIN/OPIN type '%s'", type_string());
135-
}
136-
return storage_->get(id_).ptc_.pin_num;
133+
return storage_->node_pin_num(id_);
137134
}
138135

139136
inline short t_rr_node::track_num() const {
140-
if (type() != CHANX && type() != CHANY) {
141-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'track_num' for non-CHANX/CHANY type '%s'", type_string());
142-
}
143-
return storage_->get(id_).ptc_.track_num;
137+
return storage_->node_track_num(id_);
144138
}
145139

146140
inline short t_rr_node::class_num() const {
147-
if (type() != SOURCE && type() != SINK) {
148-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'class_num' for non-SOURCE/SINK type '%s'", type_string());
149-
}
150-
return storage_->get(id_).ptc_.class_num;
141+
return storage_->node_class_num(id_);
151142
}
152143

153144
inline short t_rr_node::cost_index() const {

vpr/src/route/rr_node_storage.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,56 @@ bool t_rr_node_storage::validate() const {
455455
}
456456
return all_valid;
457457
}
458+
459+
const char* t_rr_node_storage::node_type_string(RRNodeId id) const {
460+
return rr_node_typename[node_type(id)];
461+
}
462+
t_rr_type t_rr_node_storage::node_type(RRNodeId id) const {
463+
return storage_[id].type_;
464+
}
465+
466+
void t_rr_node_storage::set_node_ptc_num(RRNodeId id, short new_ptc_num) {
467+
ptc_[id].ptc_.pin_num = new_ptc_num; //TODO: eventually remove
468+
}
469+
void t_rr_node_storage::set_node_pin_num(RRNodeId id, short new_pin_num) {
470+
if (node_type(id) != IPIN && node_type(id) != OPIN) {
471+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'pin_num' for non-IPIN/OPIN type '%s'", node_type_string(id));
472+
}
473+
ptc_[id].ptc_.pin_num = new_pin_num;
474+
}
475+
476+
void t_rr_node_storage::set_node_track_num(RRNodeId id, short new_track_num) {
477+
if (node_type(id) != CHANX && node_type(id) != CHANY) {
478+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'track_num' for non-CHANX/CHANY type '%s'", node_type_string(id));
479+
}
480+
ptc_[id].ptc_.track_num = new_track_num;
481+
}
482+
483+
void t_rr_node_storage::set_node_class_num(RRNodeId id, short new_class_num) {
484+
if (node_type(id) != SOURCE && node_type(id) != SINK) {
485+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'class_num' for non-SOURCE/SINK type '%s'", node_type_string(id));
486+
}
487+
ptc_[id].ptc_.class_num = new_class_num;
488+
}
489+
490+
short t_rr_node_storage::node_ptc_num(RRNodeId id) const {
491+
return ptc_[id].ptc_.pin_num;
492+
}
493+
short t_rr_node_storage::node_pin_num(RRNodeId id) const {
494+
if (node_type(id) != IPIN && node_type(id) != OPIN) {
495+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'pin_num' for non-IPIN/OPIN type '%s'", node_type_string(id));
496+
}
497+
return ptc_[id].ptc_.pin_num;
498+
}
499+
short t_rr_node_storage::node_track_num(RRNodeId id) const {
500+
if (node_type(id) != CHANX && node_type(id) != CHANY) {
501+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'track_num' for non-CHANX/CHANY type '%s'", node_type_string(id));
502+
}
503+
return ptc_[id].ptc_.track_num;
504+
}
505+
short t_rr_node_storage::node_class_num(RRNodeId id) const {
506+
if (node_type(id) != SOURCE && node_type(id) != SINK) {
507+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to access RR node 'class_num' for non-SOURCE/SINK type '%s'", node_type_string(id));
508+
}
509+
return ptc_[id].ptc_.class_num;
510+
}

vpr/src/route/rr_node_storage.h

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef _RR_NODE_STORAGE_
22
#define _RR_NODE_STORAGE_
33

4+
#include <exception>
5+
46
#include "rr_node_fwd.h"
57
#include "rr_graph2.h"
68
#include "vtr_log.h"
@@ -39,7 +41,7 @@
3941
* side: The side of a grid location where an IPIN or OPIN is located. *
4042
* This field is valid only for IPINs and OPINs and should be ignored *
4143
* otherwise. */
42-
struct t_rr_node_data {
44+
struct alignas(16) t_rr_node_data {
4345
int8_t cost_index_ = -1;
4446
int16_t rc_index_ = -1;
4547

@@ -54,13 +56,42 @@ struct t_rr_node_data {
5456
e_side side; //Valid only for IPINs/OPINs
5557
} dir_side_;
5658

59+
uint16_t capacity_ = 0;
60+
};
61+
62+
struct t_rr_node_ptc_data {
5763
union {
5864
int16_t pin_num;
5965
int16_t track_num;
6066
int16_t class_num;
6167
} ptc_;
68+
};
6269

63-
uint16_t capacity_ = 0;
70+
static_assert(sizeof(t_rr_node_data) == 16, "Check t_rr_node_data size");
71+
static_assert(alignof(t_rr_node_data) == 16, "Check t_rr_node_data size");
72+
73+
template<class T>
74+
struct aligned_allocator {
75+
using value_type = T;
76+
using pointer = T*;
77+
using const_pointer = const T*;
78+
using reference = T&;
79+
using const_reference = const T&;
80+
using size_type = std::size_t;
81+
using difference_type = std::ptrdiff_t;
82+
83+
pointer allocate(size_type n, const void* /*hint*/ = 0) {
84+
void* data;
85+
int ret = posix_memalign(&data, alignof(T), sizeof(T) * n);
86+
if (ret != 0) {
87+
throw std::bad_alloc();
88+
}
89+
return static_cast<pointer>(data);
90+
}
91+
92+
void deallocate(T* p, size_type /*n*/) {
93+
free(p);
94+
}
6495
};
6596

6697
// RR node and edge storage class.
@@ -74,11 +105,13 @@ class t_rr_node_storage {
74105
// No edges can be assigned if mutating the rr node array.
75106
VTR_ASSERT(!edges_read_);
76107
storage_.reserve(size);
108+
ptc_.reserve(size);
77109
}
78110
void resize(size_t size) {
79111
// No edges can be assigned if mutating the rr node array.
80112
VTR_ASSERT(!edges_read_);
81113
storage_.resize(size);
114+
ptc_.resize(size);
82115
}
83116
size_t size() const {
84117
return storage_.size();
@@ -89,6 +122,7 @@ class t_rr_node_storage {
89122

90123
void clear() {
91124
storage_.clear();
125+
ptc_.clear();
92126
first_edge_.clear();
93127
fan_in_.clear();
94128
edge_src_node_.clear();
@@ -101,6 +135,7 @@ class t_rr_node_storage {
101135

102136
void shrink_to_fit() {
103137
storage_.shrink_to_fit();
138+
ptc_.shrink_to_fit();
104139
first_edge_.shrink_to_fit();
105140
fan_in_.shrink_to_fit();
106141
edge_src_node_.shrink_to_fit();
@@ -112,6 +147,7 @@ class t_rr_node_storage {
112147
// No edges can be assigned if mutating the rr node array.
113148
VTR_ASSERT(!edges_read_);
114149
storage_.emplace_back();
150+
ptc_.emplace_back();
115151
}
116152

117153
node_idx_iterator begin() const;
@@ -130,6 +166,25 @@ class t_rr_node_storage {
130166

131167
friend class t_rr_node;
132168

169+
/****************
170+
* Node methods *
171+
****************/
172+
173+
const char* node_type_string(RRNodeId id) const;
174+
t_rr_type node_type(RRNodeId id) const;
175+
176+
/* PTC set methods */
177+
void set_node_ptc_num(RRNodeId id, short);
178+
void set_node_pin_num(RRNodeId id, short); //Same as set_ptc_num() by checks type() is consistent
179+
void set_node_track_num(RRNodeId id, short); //Same as set_ptc_num() by checks type() is consistent
180+
void set_node_class_num(RRNodeId id, short); //Same as set_ptc_num() by checks type() is consistent
181+
182+
/* PTC get methods */
183+
short node_ptc_num(RRNodeId id) const;
184+
short node_pin_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent
185+
short node_track_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent
186+
short node_class_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent
187+
133188
/****************
134189
* Edge methods *
135190
****************/
@@ -290,7 +345,8 @@ class t_rr_node_storage {
290345
// Verify that first_edge_ array correctly partitions rr edge data.
291346
bool verify_first_edges() const;
292347

293-
vtr::vector<RRNodeId, t_rr_node_data> storage_;
348+
vtr::vector<RRNodeId, t_rr_node_data, aligned_allocator<t_rr_node_data>> storage_;
349+
vtr::vector<RRNodeId, t_rr_node_ptc_data> ptc_;
294350
vtr::vector<RRNodeId, RREdgeId> first_edge_;
295351
vtr::vector<RRNodeId, t_edge_size> fan_in_;
296352

0 commit comments

Comments
 (0)