after profiling with intel vtune, mitigate some performance hotspots. may give a 10-20% performance boost during preprocessing

This commit is contained in:
Dennis Luxen 2015-01-14 17:26:59 +01:00
parent 0077856d2f
commit 39edbcbabd
2 changed files with 37 additions and 15 deletions

View File

@ -76,6 +76,16 @@ template <typename NodeID, typename Key> class UnorderedMapStorage
Key &operator[](const NodeID node) { return nodes[node]; } Key &operator[](const NodeID node) { return nodes[node]; }
Key peek_index(const NodeID node) const
{
const auto iter = nodes.find(node);
if (std::end(nodes) != iter)
{
return iter->second;
}
return Key(-1);
}
Key const &operator[](const NodeID node) const Key const &operator[](const NodeID node) const
{ {
auto iter = nodes.find(node); auto iter = nodes.find(node);
@ -132,13 +142,13 @@ class BinaryHeap
Data &GetData(NodeID node) Data &GetData(NodeID node)
{ {
const Key index = node_index[node]; const Key index = node_index.peek_index(node);
return inserted_nodes[index].data; return inserted_nodes[index].data;
} }
Data const &GetData(NodeID node) const Data const &GetData(NodeID node) const
{ {
const Key index = node_index[node]; const Key index = node_index.peek_index(node);
return inserted_nodes[index].data; return inserted_nodes[index].data;
} }
@ -148,16 +158,16 @@ class BinaryHeap
return inserted_nodes[index].weight; return inserted_nodes[index].weight;
} }
bool WasRemoved(const NodeID node) bool WasRemoved(const NodeID node) const
{ {
BOOST_ASSERT(WasInserted(node)); BOOST_ASSERT(WasInserted(node));
const Key index = node_index[node]; const Key index = node_index.peek_index(node);
return inserted_nodes[index].key == 0; return inserted_nodes[index].key == 0;
} }
bool WasInserted(const NodeID node) bool WasInserted(const NodeID node)
{ {
const Key index = node_index[node]; const Key index = node_index.peek_index(node);
if (index >= static_cast<Key>(inserted_nodes.size())) if (index >= static_cast<Key>(inserted_nodes.size()))
{ {
return false; return false;
@ -200,7 +210,7 @@ class BinaryHeap
void DecreaseKey(NodeID node, Weight weight) void DecreaseKey(NodeID node, Weight weight)
{ {
BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node); BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node);
const Key &index = node_index[node]; const Key &index = node_index.peek_index(node);
Key &key = inserted_nodes[index].key; Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0); BOOST_ASSERT(key >= 0);
@ -235,11 +245,12 @@ class BinaryHeap
{ {
const Key droppingIndex = heap[key].index; const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight; const Weight weight = heap[key].weight;
const Key heap_size = static_cast<Key>(heap.size());
Key nextKey = key << 1; Key nextKey = key << 1;
while (nextKey < static_cast<Key>(heap.size())) while (nextKey < heap_size)
{ {
const Key nextKeyOther = nextKey + 1; const Key nextKeyOther = nextKey + 1;
if ((nextKeyOther < static_cast<Key>(heap.size())) && if ((nextKeyOther < heap_size) &&
(heap[nextKey].weight > heap[nextKeyOther].weight)) (heap[nextKey].weight > heap[nextKeyOther].weight))
{ {
nextKey = nextKeyOther; nextKey = nextKeyOther;

View File

@ -38,12 +38,12 @@ template <typename NodeID, typename Key> class XORFastHashStorage
public: public:
struct HashCell struct HashCell
{ {
Key key;
NodeID id;
unsigned time; unsigned time;
NodeID id;
Key key;
HashCell() HashCell()
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()), : time(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
time(std::numeric_limits<unsigned>::max()) key(std::numeric_limits<unsigned>::max())
{ {
} }
@ -51,7 +51,7 @@ template <typename NodeID, typename Key> class XORFastHashStorage
operator Key() const { return key; } operator Key() const { return key; }
void operator=(const Key &key_to_insert) { key = key_to_insert; } void operator=(const Key key_to_insert) { key = key_to_insert; }
}; };
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {} explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
@ -64,18 +64,29 @@ template <typename NodeID, typename Key> class XORFastHashStorage
++position %= (2 << 16); ++position %= (2 << 16);
} }
positions[position].id = node;
positions[position].time = current_timestamp; positions[position].time = current_timestamp;
positions[position].id = node;
return positions[position]; return positions[position];
} }
// peek into table, get key for node, think of it as a read-only operator[]
Key peek_index(const NodeID node) const
{
unsigned short position = fast_hasher(node);
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
{
++position %= (2 << 16);
}
return positions[position].key;
}
void Clear() void Clear()
{ {
++current_timestamp; ++current_timestamp;
if (std::numeric_limits<unsigned>::max() == current_timestamp) if (std::numeric_limits<unsigned>::max() == current_timestamp)
{ {
positions.clear(); positions.clear();
positions.resize((2 << 16)); // positions.resize((2 << 16));
} }
} }