-
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New transport based on KCP on top of UDP. This transport appears to have big performance improvement over the default TCP transport. In the mosters sync benchmark these are the results (note units changed): ### TCP > Time Millisecond Median:27.49 Min:3.69 Max:439.36 Avg:50.71 Std:69.79 SampleCount: 256 Sum: 12980.73 ### KCP > Time Microsecond Median:7699.10 Min:2381.30 Max:25384.80 Avg:8393.94 Std:3804.06 SampleCount: 256 Sum: 2148847.80 It is 600% faster and much smaller jitter in my machine.
- Loading branch information
Showing
29 changed files
with
2,149 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: InternalsVisibleTo("Mirror.Tests.Runtime")] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Mirror.KCP | ||
{ | ||
class ByteBuffer : IDisposable | ||
{ | ||
int writeIndex; | ||
static readonly List<ByteBuffer> pool = new List<ByteBuffer>(); | ||
const int PoolMaxCount = 200; | ||
|
||
ByteBuffer(int capacity) | ||
{ | ||
RawBuffer = new byte[capacity]; | ||
Capacity = capacity; | ||
ReaderIndex = 0; | ||
writeIndex = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Construct a capacity length byte buffer ByteBuffer object | ||
/// </summary> | ||
/// <param name="capacity">Initial capacity</param> | ||
/// <param name="fromPool"> | ||
/// true means to obtain a pooled ByteBuffer object, the pooled object must be pushed into the pool after calling Dispose, this method is thread-safe. | ||
/// When true, the actual capacity value of the object obtained from the pool | ||
/// </param> | ||
/// <returns>ByteBuffer object</returns> | ||
public static ByteBuffer Allocate(int capacity) | ||
{ | ||
ByteBuffer bbuf; | ||
if (pool.Count == 0) | ||
{ | ||
bbuf = new ByteBuffer(capacity); | ||
return bbuf; | ||
} | ||
int lastIndex = pool.Count - 1; | ||
bbuf = pool[lastIndex]; | ||
pool.RemoveAt(lastIndex); | ||
return bbuf; | ||
|
||
} | ||
|
||
/// <summary> | ||
/// According to the value, determine the nearest 2nd power greater than this length, such as length=7, the return value is 8; length=12, then 16 | ||
/// </summary> | ||
/// <param name="value">Reference capacity</param> | ||
/// <returns>The nearest second power greater than the reference capacity</returns> | ||
int FixLength(int value) | ||
{ | ||
if (value == 0) | ||
{ | ||
return 1; | ||
} | ||
value--; | ||
value |= value >> 1; | ||
value |= value >> 2; | ||
value |= value >> 4; | ||
value |= value >> 8; | ||
value |= value >> 16; | ||
return value + 1; | ||
} | ||
|
||
/// <summary> | ||
/// Determine the size of the internal byte buffer array | ||
/// </summary> | ||
/// <param name="currLen">Current capacity</param> | ||
/// <param name="futureLen">Future capacity</param> | ||
/// <returns>The maximum capacity of the current buffer</returns> | ||
void FixSizeAndReset(int currLen, int futureLen) | ||
{ | ||
if (futureLen > currLen) | ||
{ | ||
//Determine the size of the internal byte buffer with twice the original size to the power of 2 | ||
int size = FixLength(currLen) * 2; | ||
if (futureLen > size) | ||
{ | ||
//Determine the size of the internal byte buffer by twice the power of the future size | ||
size = FixLength(futureLen) * 2; | ||
} | ||
byte[] newbuf = new byte[size]; | ||
Array.Copy(RawBuffer, 0, newbuf, 0, currLen); | ||
RawBuffer = newbuf; | ||
Capacity = size; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Write length bytes starting from startIndex of bytes byte array to this buffer | ||
/// </summary> | ||
/// <param name="bytes">Byte data to be written</param> | ||
/// <param name="startIndex">Start position of writing</param> | ||
/// <param name="length">Length written</param> | ||
public void WriteBytes(byte[] bytes, int startIndex, int length) | ||
{ | ||
if (length <= 0 || startIndex < 0) return; | ||
|
||
int total = length + writeIndex; | ||
int len = RawBuffer.Length; | ||
FixSizeAndReset(len, total); | ||
Array.Copy(bytes, startIndex, RawBuffer, writeIndex, length); | ||
writeIndex = total; | ||
} | ||
|
||
public int ReaderIndex { get; private set; } | ||
|
||
public int ReadableBytes => writeIndex - ReaderIndex; | ||
|
||
public int Capacity { get; private set; } | ||
|
||
public byte[] RawBuffer { get; private set; } | ||
|
||
public void Clear() | ||
{ | ||
ReaderIndex = 0; | ||
writeIndex = 0; | ||
Capacity = RawBuffer.Length; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
if (pool.Count < PoolMaxCount) | ||
{ | ||
Clear(); | ||
pool.Add(this); | ||
return; | ||
} | ||
ReaderIndex = 0; | ||
writeIndex = 0; | ||
Capacity = 0; | ||
RawBuffer = null; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "KCP", | ||
"references": [ | ||
"GUID:30817c1a0e6d646d99c048fc403f5979", | ||
"GUID:f51ebe6a0ceec4240a699833d6309b23" | ||
], | ||
"includePlatforms": [], | ||
"excludePlatforms": [], | ||
"allowUnsafeCode": false, | ||
"overrideReferences": false, | ||
"precompiledReferences": [], | ||
"autoReferenced": true, | ||
"defineConstraints": [], | ||
"versionDefines": [], | ||
"noEngineReferences": false | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.