Skip to content

Commit

Permalink
fix(shm): avoid false sharing when updating block weights during refi…
Browse files Browse the repository at this point in the history
…nement for small k (#78)
  • Loading branch information
DanielSeemaier authored Feb 18, 2025
1 parent 1831701 commit dce3747
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions kaminpar-shm/refinement/lp/lp_refiner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ class LPRefinerImpl final
_p_graph = &p_graph;
_p_ctx = &p_ctx;

if (_p_graph->k() < 1024) {
_aligned_block_weights.resize(_p_graph->k());
_p_graph->pfor_blocks([&](const BlockID b) {
_aligned_block_weights[b].value = _p_graph->block_weight(b);
});
} else {
_aligned_block_weights.resize(0);
}

Base::initialize(_graph, _p_ctx->k);

const std::size_t max_iterations =
Expand All @@ -83,6 +92,12 @@ class LPRefinerImpl final
}
}

if (!_aligned_block_weights.empty()) {
_p_graph->pfor_blocks([&](const BlockID b) {
_p_graph->set_block_weight(b, _aligned_block_weights[b].value);
});
}

return true;
}

Expand All @@ -96,11 +111,15 @@ class LPRefinerImpl final
}

[[nodiscard]] BlockWeight initial_cluster_weight(const BlockID b) {
return _p_graph->block_weight(b);
return _aligned_block_weights.empty()
? _p_graph->block_weight(b)
: __atomic_load_n(&_aligned_block_weights[b].value, __ATOMIC_RELAXED);
}

[[nodiscard]] BlockWeight cluster_weight(const BlockID b) {
return _p_graph->block_weight(b);
return _aligned_block_weights.empty()
? _p_graph->block_weight(b)
: __atomic_load_n(&_aligned_block_weights[b].value, __ATOMIC_RELAXED);
}

[[nodiscard]] bool accept_neighbor(const NodeID u, const NodeID v) {
Expand All @@ -113,7 +132,27 @@ class LPRefinerImpl final
const BlockWeight delta,
const BlockWeight max_weight
) {
return _p_graph->move_block_weight(old_block, new_block, delta, max_weight);
if (_aligned_block_weights.empty()) {
return _p_graph->move_block_weight(old_block, new_block, delta, max_weight);
} else {
for (BlockWeight new_weight =
__atomic_load_n(&_aligned_block_weights[new_block].value, __ATOMIC_RELAXED);
new_weight + delta <= max_weight;) {
if (__atomic_compare_exchange_n(
&_aligned_block_weights[new_block].value,
&new_weight,
new_weight + delta,
false,
__ATOMIC_RELAXED,
__ATOMIC_RELAXED
)) {
__atomic_fetch_sub(&_aligned_block_weights[old_block].value, delta, __ATOMIC_RELAXED);
return true;
}
}

return false;
}
}

void reassign_cluster_weights(
Expand Down Expand Up @@ -279,6 +318,12 @@ class LPRefinerImpl final
const RefinementContext &_r_ctx;

std::span<const NodeID> _communities;

struct alignas(64) AlignedBlockWeight {
BlockWeight value;
};

StaticArray<AlignedBlockWeight> _aligned_block_weights;
};

class LPRefinerImplWrapper {
Expand Down

0 comments on commit dce3747

Please sign in to comment.