X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=lightning%2Fsrc%2Frouting%2Fscoring.rs;fp=lightning%2Fsrc%2Frouting%2Fscoring.rs;h=cde615b9f10578d789826a1e480c0c44ce143eba;hb=4c54ae375abd00812c7364f975a828a45d0fef69;hp=42a565aee95b908b4a60ddf6c99b10ba98899987;hpb=d8748b05c5ae3917656a5debc77e14a7767225c6;p=rust-lightning diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 42a565ae..cde615b9 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -780,6 +780,7 @@ impl ProbabilisticScoringDecayParameters { /// Direction is defined in terms of [`NodeId`] partial ordering, where the source node is the /// first node in the ordering of the channel's counterparties. Thus, swapping the two liquidity /// offset fields gives the opposite direction. +#[repr(C)] // Force the fields in memory to be in the order we specify struct ChannelLiquidity { /// Lower channel liquidity bound in terms of an offset from zero. min_liquidity_offset_msat: u64, @@ -797,6 +798,16 @@ struct ChannelLiquidity { offset_history_last_updated: Duration, } +// Check that the liquidity HashMap's entries sit on round cache lines. +// +// Specifically, the first cache line will have the key, the liquidity offsets, and the total +// points tracked in the historical tracker. +// +// The next two cache lines will have the historical points, which we only access last during +// scoring, followed by the last_updated `Duration`s (which we do not need during scoring). +const _LIQUIDITY_MAP_SIZING_CHECK: usize = 192 - ::core::mem::size_of::<(u64, ChannelLiquidity)>(); +const _LIQUIDITY_MAP_SIZING_CHECK_2: usize = ::core::mem::size_of::<(u64, ChannelLiquidity)>() - 192; + /// A snapshot of [`ChannelLiquidity`] in one direction assuming a certain channel capacity and /// decayed with a given half life. struct DirectedChannelLiquidity, HT: Deref, T: Deref> { @@ -1487,10 +1498,24 @@ mod bucketed_history { // between the 12,000th sat and 24,000th sat, while only needing to store and operate on 32 // buckets in total. - const BUCKET_START_POS: [u16; 33] = [ - 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 3072, 4096, 6144, 8192, 10240, 12288, - 13312, 14336, 15360, 15872, 16128, 16256, 16320, 16352, 16368, 16376, 16380, 16382, 16383, 16384, - ]; + // By default u16s may not be cache-aligned, but we'd rather not have to read a third cache + // line just to access it + #[repr(align(128))] + struct BucketStartPos([u16; 33]); + impl BucketStartPos { + const fn new() -> Self { + Self([ + 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 3072, 4096, 6144, 8192, 10240, 12288, + 13312, 14336, 15360, 15872, 16128, 16256, 16320, 16352, 16368, 16376, 16380, 16382, 16383, 16384, + ]) + } + } + impl core::ops::Index for BucketStartPos { + type Output = u16; + #[inline(always)] + fn index(&self, index: usize) -> &u16 { &self.0[index] } + } + const BUCKET_START_POS: BucketStartPos = BucketStartPos::new(); const LEGACY_TO_BUCKET_RANGE: [(u8, u8); 8] = [ (0, 12), (12, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 20), (20, 32) @@ -1628,10 +1653,11 @@ mod bucketed_history { impl_writeable_tlv_based!(LegacyHistoricalBucketRangeTracker, { (0, buckets, required) }); #[derive(Clone, Copy)] + #[repr(C)] // Force the fields in memory to be in the order we specify. pub(super) struct HistoricalLiquidityTracker { + total_valid_points_tracked: u64, min_liquidity_offset_history: HistoricalBucketRangeTracker, max_liquidity_offset_history: HistoricalBucketRangeTracker, - total_valid_points_tracked: u64, } impl HistoricalLiquidityTracker {