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