perf(network): Improve performance by refactoring loop logic and removing unused static variables#2659
perf(network): Improve performance by refactoring loop logic and removing unused static variables#2659Caball009 wants to merge 4 commits into
Conversation
7ebd8f1 to
a2267a1
Compare
|
I think it would be nice if we can change the signature of NetPacket from |
Perhaps I can just put the relevant logic from |
I think it's best to do this in a separate pull request because it involves another set of changes. |
3fe1916 to
d4f75e9
Compare
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameNetwork/Transport.cpp | Introduces bufferIndex to avoid restarting inner loops, removes static counters, and re-enables a DEBUG_ASSERTCRASH that was previously commented out. The bufferIndex is shared between m_delayedInBuffer (latency path) and m_inBuffer (normal path), which could misplace packets if m_useLatency toggles mid-call. |
| Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | Removes two unused static debug counters, converts while loops to range-for, and adds an early break on empty m_inBuffer slots. The early break is safe because the buffer invariant is maintained by the write/clear ordering. |
| Core/GameEngine/Source/GameNetwork/LANAPI.cpp | Replaces MAX_MESSAGES with ARRAY_SIZE and adds an early break on empty slots. The existing LANbuttonPushed guard is preserved in the loop condition. |
| Core/GameEngine/Source/GameNetwork/NAT.cpp | Replaces MAX_MESSAGES with ARRAY_SIZE and adds an early break on empty slots. Minimal, low-risk change consistent with the rest of the PR. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UDP as UDP Socket
participant TR as Transport::doRecv()
participant IB as m_inBuffer[]
participant DIB as m_delayedInBuffer[]
participant CM as ConnectionManager::doRelay()
participant LAN as LANAPI::update()
participant NAT as NAT::connectionUpdate()
UDP->>TR: Read(packet)
TR->>TR: bufferIndex starts at 0 (local)
alt "m_useLatency == true (DEBUG only)"
TR->>DIB: fill at bufferIndex, ++bufferIndex
Note over TR,DIB: bufferIndex shared with m_inBuffer path
else "m_useLatency == false"
TR->>IB: fill at bufferIndex, ++bufferIndex
end
Note over TR,IB: Early break added: readers stop at first empty slot
CM->>IB: "iterate i=0..N, break on length==0"
IB->>CM: process packet, clear slot
LAN->>IB: "iterate i=0..N, break on length==0"
IB->>LAN: process packet, clear slot
NAT->>IB: "iterate i=0..N, break on length==0"
IB->>NAT: process packet, clear slot
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UDP as UDP Socket
participant TR as Transport::doRecv()
participant IB as m_inBuffer[]
participant DIB as m_delayedInBuffer[]
participant CM as ConnectionManager::doRelay()
participant LAN as LANAPI::update()
participant NAT as NAT::connectionUpdate()
UDP->>TR: Read(packet)
TR->>TR: bufferIndex starts at 0 (local)
alt "m_useLatency == true (DEBUG only)"
TR->>DIB: fill at bufferIndex, ++bufferIndex
Note over TR,DIB: bufferIndex shared with m_inBuffer path
else "m_useLatency == false"
TR->>IB: fill at bufferIndex, ++bufferIndex
end
Note over TR,IB: Early break added: readers stop at first empty slot
CM->>IB: "iterate i=0..N, break on length==0"
IB->>CM: process packet, clear slot
LAN->>IB: "iterate i=0..N, break on length==0"
IB->>LAN: process packet, clear slot
NAT->>IB: "iterate i=0..N, break on length==0"
IB->>NAT: process packet, clear slot
Reviews (4): Last reviewed commit: "Used '>' and '<=' instead of '==' and '!..." | Re-trigger Greptile
| m_transport->m_inBuffer[i].length = 0; | ||
| } | ||
| } else { | ||
| break; |
There was a problem hiding this comment.
Alternatively could do early breaks in the loops. But its ok either way.
| } | ||
| else | ||
| { | ||
| break; |
There was a problem hiding this comment.
So there cannot be non-zero buffer after a zero buffer, yes?
There was a problem hiding this comment.
That's right. Transport::doRecv should handle that correctly.
| for (Int i = 0; i < MAX_MESSAGES; ++i) { | ||
| if (m_transport->m_inBuffer[i].length != 0) { | ||
| for (size_t i = 0; i < ARRAY_SIZE(m_transport->m_inBuffer); ++i) { | ||
| if (m_transport->m_inBuffer[i].length > 0) { |
There was a problem hiding this comment.
Status quo: Compares with > 0, != 0
Expectation:
> 0, <= 0
or
== 0, != 0
There was a problem hiding this comment.
I've split this off to a separate commit. I do think this is the right comparator, though, as long as length is still signed.
The original code already does it this way here:
There was a problem hiding this comment.
I can change the == 0 cases to <= 0 if you like.
I can put the loop logic in another PR and put #2866 in here to replace all memory pooled uses of |
|
Whatever makes most sense. |
This PR makes modest performance improvements:
See commits for cleaner diffs.
TODO: