Skip to content

Commit 86e0249

Browse files
committed
Optimizations of the UnifiedNetcodeTransport.
1 parent 4512b39 commit 86e0249

1 file changed

Lines changed: 55 additions & 15 deletions

File tree

com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,69 @@
44
using Unity.Burst;
55
using Unity.Burst.Intrinsics;
66
using Unity.Collections;
7+
using Unity.Collections.LowLevel.Unsafe;
78
using Unity.Entities;
89
using Unity.NetCode;
910
using Unity.Netcode.Transports.UTP;
11+
using UnityEngine;
1012

1113
namespace Unity.Netcode.Unified
1214
{
1315
[BurstCompile]
16+
internal unsafe struct FixedBytes1280
17+
{
18+
public fixed byte Buffer[1280];
19+
public int Length;
20+
21+
// Returns a direct pointer to the data in the buffer.
22+
// Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
23+
// Note that the buffer MUST outlive the returned pointer, as it is an alias.
24+
public static byte* GetUnsafePtr(in FixedBytes1280 data)
25+
{
26+
fixed (byte* buffer = data.Buffer)
27+
{
28+
return buffer;
29+
}
30+
}
31+
32+
// Returns a native array that is an alias of the existing data without copying it
33+
// Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
34+
// Note that the buffer MUST outlive the returned array, as it is an alias.
35+
public static NativeArray<byte> ToNativeArray(in FixedBytes1280 data)
36+
{
37+
var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(GetUnsafePtr(data), data.Length, Allocator.None);
38+
#if ENABLE_UNITY_COLLECTIONS_CHECKS
39+
var safety = CollectionHelper.CreateSafetyHandle(Allocator.None);
40+
NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, safety);
41+
#endif
42+
return array;
43+
}
44+
}
45+
46+
[BurstCompile]
1447
internal struct TransportRpc : IOutOfBandRpcCommand, IRpcCommandSerializer<TransportRpc>
1548
{
16-
public FixedList4096Bytes<byte> Buffer;
49+
public FixedBytes1280 Buffer;
1750
public ulong Order;
1851

1952
public unsafe void Serialize(ref DataStreamWriter writer, in RpcSerializerState state, in TransportRpc data)
2053
{
2154
writer.WriteULong(data.Order);
2255
writer.WriteInt(data.Buffer.Length);
23-
var span = new Span<byte>(data.Buffer.GetUnsafePtr(), data.Buffer.Length);
56+
var span = new Span<byte>(FixedBytes1280.GetUnsafePtr(data.Buffer), data.Buffer.Length);
2457
writer.WriteBytes(span);
2558
}
2659

2760
public unsafe void Deserialize(ref DataStreamReader reader, in RpcDeserializerState state, ref TransportRpc data)
2861
{
2962
data.Order = reader.ReadULong();
3063
var length = reader.ReadInt();
31-
data.Buffer = new FixedList4096Bytes<byte>()
64+
data.Buffer = new FixedBytes1280
3265
{
3366
Length = length
3467
};
35-
var span = new Span<byte>(data.Buffer.GetUnsafePtr(), length);
68+
69+
var span = new Span<byte>(FixedBytes1280.GetUnsafePtr(data.Buffer), length);
3670
reader.ReadBytes(span);
3771
}
3872

@@ -81,7 +115,6 @@ public void OnUpdate(ref SystemState state)
81115
}
82116
}
83117

84-
85118
internal partial class UnifiedNetcodeUpdateSystem : SystemBase
86119
{
87120
public UnifiedNetcodeTransport Transport;
@@ -96,11 +129,11 @@ public void Disconnect(Connection connection)
96129
protected override void OnUpdate()
97130
{
98131
using var commandBuffer = new EntityCommandBuffer(Allocator.Temp);
99-
foreach(var (request, rpc, entity) in SystemAPI.Query<RefRO<ReceiveRpcCommandRequest>, RefRW<TransportRpc>>().WithEntityAccess())
132+
foreach(var (request, rpc, entity) in SystemAPI.Query<RefRO<ReceiveRpcCommandRequest>, RefRO<TransportRpc>>().WithEntityAccess())
100133
{
101134
var connectionId = SystemAPI.GetComponent<NetworkId>(request.ValueRO.SourceConnection).Value;
102135

103-
var buffer = rpc.ValueRW.Buffer;
136+
var buffer = rpc.ValueRO.Buffer;
104137
try
105138
{
106139
Transport.DispatchMessage(connectionId, buffer, rpc.ValueRO.Order);
@@ -124,7 +157,7 @@ protected override void OnUpdate()
124157

125158
internal class UnifiedNetcodeTransport : NetworkTransport
126159
{
127-
private const int k_MaxPacketSize = 1300;
160+
private const int k_MaxPacketSize = 1280;
128161

129162
private int m_ServerClientId = -1;
130163
public override ulong ServerClientId => (ulong)m_ServerClientId;
@@ -140,27 +173,34 @@ private class ConnectionInfo
140173
public Connection Connection;
141174
public ulong LastSent;
142175
public ulong LastReceived;
143-
public Dictionary<ulong, FixedList4096Bytes<byte>> DeferredMessages;
176+
public Dictionary<ulong, FixedBytes1280> DeferredMessages;
144177
}
145178

146179
private Dictionary<int, ConnectionInfo> m_Connections;
147180

148-
internal void DispatchMessage(int connectionId, FixedList4096Bytes<byte> buffer, ulong order)
181+
internal void DispatchMessage(int connectionId, in FixedBytes1280 buffer, ulong order)
149182
{
150183
var connectionInfo = m_Connections[connectionId];
151184

185+
if (order <= connectionInfo.LastReceived)
186+
{
187+
Debug.LogWarning("Received duplicate message, ignoring.");
188+
return;
189+
}
190+
152191
if (order != connectionInfo.LastReceived + 1)
153192
{
154193
if (connectionInfo.DeferredMessages == null)
155194
{
156-
connectionInfo.DeferredMessages = new Dictionary<ulong, FixedList4096Bytes<byte>>();
195+
connectionInfo.DeferredMessages = new Dictionary<ulong, FixedBytes1280>();
157196
}
158197

159198
connectionInfo.DeferredMessages[order] = buffer;
160199
return;
161200
}
162201

163-
var reader = new DataStreamReader(buffer.ToNativeArray(Allocator.Temp));
202+
using var arr = FixedBytes1280.ToNativeArray(buffer);
203+
var reader = new DataStreamReader(arr);
164204
if (connectionInfo.ReceiveQueue == null)
165205
{
166206
connectionInfo.ReceiveQueue = new BatchedReceiveQueue(reader);
@@ -176,7 +216,7 @@ internal void DispatchMessage(int connectionId, FixedList4096Bytes<byte> buffer,
176216
var next = order + 1;
177217
while (connectionInfo.DeferredMessages.Remove(next, out var nextBuffer))
178218
{
179-
reader = new DataStreamReader(nextBuffer.ToNativeArray(Allocator.Temp));
219+
reader = new DataStreamReader(FixedBytes1280.ToNativeArray(nextBuffer));
180220
connectionInfo.ReceiveQueue.PushReader(reader);
181221
connectionInfo.LastReceived = next;
182222
++next;
@@ -205,10 +245,10 @@ public override unsafe void Send(ulong clientId, ArraySegment<byte> payload, Net
205245
{
206246
var rpc = new TransportRpc
207247
{
208-
Buffer = new FixedList4096Bytes<byte>(),
248+
Buffer = new FixedBytes1280(),
209249
};
210250

211-
var writer = new DataStreamWriter(rpc.Buffer.GetUnsafePtr(), k_MaxPacketSize);
251+
var writer = new DataStreamWriter(FixedBytes1280.GetUnsafePtr(rpc.Buffer), k_MaxPacketSize);
212252

213253
var amount = connectionInfo.SendQueue.FillWriterWithBytes(ref writer, k_MaxPacketSize);
214254
rpc.Buffer.Length = amount;

0 commit comments

Comments
 (0)