@@ -760,22 +760,32 @@ where
760
760
}
761
761
}
762
762
763
+ // Fetching values from this struct is very performance sensitive during routefinding. Thus, we
764
+ // want to ensure that all of the fields we care about (all of them except `last_update_message`)
765
+ // sit on the same cache line.
766
+ //
767
+ // We do this by using `repr(C)`, which forces the struct to be laid out in memory the way we write
768
+ // it (ensuring `last_update_message` hangs off the end and no fields are reordered after it), and
769
+ // `align(32)`, ensuring the struct starts either at the start, or in the middle, of a 64b x86-64
770
+ // cache line. This ensures the beginning fields (which are 31 bytes) all sit in the same cache
771
+ // line.
772
+ #[ repr( C , align( 32 ) ) ]
763
773
#[ derive( Clone , Debug , PartialEq , Eq ) ]
764
774
/// Details about one direction of a channel as received within a [`ChannelUpdate`].
765
775
pub struct ChannelUpdateInfo {
766
- /// When the last update to the channel direction was issued.
767
- /// Value is opaque, as set in the announcement.
768
- pub last_update : u32 ,
769
- /// Whether the channel can be currently used for payments (in this one direction).
770
- pub enabled : bool ,
771
- /// The difference in CLTV values that you must have when routing through this channel.
772
- pub cltv_expiry_delta : u16 ,
773
776
/// The minimum value, which must be relayed to the next hop via the channel
774
777
pub htlc_minimum_msat : u64 ,
775
778
/// The maximum value which may be relayed to the next hop via the channel.
776
779
pub htlc_maximum_msat : u64 ,
777
780
/// Fees charged when the channel is used for routing
778
781
pub fees : RoutingFees ,
782
+ /// When the last update to the channel direction was issued.
783
+ /// Value is opaque, as set in the announcement.
784
+ pub last_update : u32 ,
785
+ /// The difference in CLTV values that you must have when routing through this channel.
786
+ pub cltv_expiry_delta : u16 ,
787
+ /// Whether the channel can be currently used for payments (in this one direction).
788
+ pub enabled : bool ,
779
789
/// Most recent update for the channel received from the network
780
790
/// Mostly redundant with the data we store in fields explicitly.
781
791
/// Everything else is useful only for sending out for initial routing sync.
@@ -843,22 +853,46 @@ impl Readable for ChannelUpdateInfo {
843
853
}
844
854
}
845
855
856
+ // Fetching values from this struct is very performance sensitive during routefinding. Thus, we
857
+ // want to ensure that all of the fields we care about (all of them except `last_update_message`
858
+ // and `announcement_received_time`) sit on the same cache line.
859
+ //
860
+ // Sadly, this is not possible, however we can still do okay - all of the fields before
861
+ // `one_to_two` and `two_to_one` are just under 128 bytes long, so we can ensure they sit on
862
+ // adjacent cache lines (which are generally fetched together in x86_64 processors).
863
+ //
864
+ // This leaves only the two directional channel info structs on separate cache lines.
865
+ //
866
+ // We accomplish this using `repr(C)`, which forces the struct to be laid out in memory the way we
867
+ // write it (ensuring the fields we care about are at the start of the struct) and `align(128)`,
868
+ // ensuring the struct starts at the beginning of two adjacent 64b x86-64 cache lines.
869
+ #[ repr( align( 128 ) , C ) ]
846
870
#[ derive( Clone , Debug , Eq ) ]
847
871
/// Details about a channel (both directions).
848
872
/// Received within a channel announcement.
849
873
pub struct ChannelInfo {
850
874
/// Protocol features of a channel communicated during its announcement
851
875
pub features : ChannelFeatures ,
876
+
852
877
/// Source node of the first direction of a channel
853
878
pub node_one : NodeId ,
854
- /// Details about the first direction of a channel
855
- pub one_to_two : Option < ChannelUpdateInfo > ,
879
+
856
880
/// Source node of the second direction of a channel
857
881
pub node_two : NodeId ,
858
- /// Details about the second direction of a channel
859
- pub two_to_one : Option < ChannelUpdateInfo > ,
882
+
883
+ /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_one`].
884
+ pub ( crate ) node_one_counter : u32 ,
885
+ /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_two`].
886
+ pub ( crate ) node_two_counter : u32 ,
887
+
860
888
/// The channel capacity as seen on-chain, if chain lookup is available.
861
889
pub capacity_sats : Option < u64 > ,
890
+
891
+ /// Details about the first direction of a channel
892
+ pub one_to_two : Option < ChannelUpdateInfo > ,
893
+ /// Details about the second direction of a channel
894
+ pub two_to_one : Option < ChannelUpdateInfo > ,
895
+
862
896
/// An initial announcement of the channel
863
897
/// Mostly redundant with the data we store in fields explicitly.
864
898
/// Everything else is useful only for sending out for initial routing sync.
@@ -868,11 +902,6 @@ pub struct ChannelInfo {
868
902
/// (which we can probably assume we are - no-std environments probably won't have a full
869
903
/// network graph in memory!).
870
904
announcement_received_time : u64 ,
871
-
872
- /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_one`].
873
- pub ( crate ) node_one_counter : u32 ,
874
- /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_two`].
875
- pub ( crate ) node_two_counter : u32 ,
876
905
}
877
906
878
907
impl PartialEq for ChannelInfo {
0 commit comments