perf: Pack small 32 bit negatives efficiently

This commit is contained in:
Paul Pacheco 2019-03-30 13:13:19 -05:00
parent 3ec7f6c1d0
commit 480af1aa6c
8 changed files with 76 additions and 22 deletions

View File

@ -229,7 +229,7 @@ bool WriteParameters(NetworkWriter writer)
if (par.type == AnimatorControllerParameterType.Int)
{
int newIntValue = animator.GetInteger(par.nameHash);
writer.WritePackedUInt32((uint)newIntValue);
writer.WritePackedInt32(newIntValue);
}
else if (par.type == AnimatorControllerParameterType.Float)
{
@ -256,7 +256,7 @@ void ReadParameters(NetworkReader reader)
AnimatorControllerParameter par = parameters[i];
if (par.type == AnimatorControllerParameterType.Int)
{
int newIntValue = (int)reader.ReadPackedUInt32();
int newIntValue = reader.ReadPackedInt32();
animator.SetInteger(par.nameHash, newIntValue);
}
else if (par.type == AnimatorControllerParameterType.Float)

View File

@ -462,7 +462,7 @@ void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker, MethodDefi
// read id and store in a local variable
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkReaderReadPacked32));
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkReaderReadPackedUInt32));
serWorker.Append(serWorker.Create(OpCodes.Stloc, tmpValue));
if (foundMethod != null)

View File

@ -101,10 +101,12 @@ class Weaver
public static MethodReference NetworkServerGetLocalClientActive;
public static MethodReference NetworkClientGetActive;
public static MethodReference UBehaviourIsServer;
public static MethodReference NetworkReaderReadPacked32;
public static MethodReference NetworkReaderReadPackedUInt32;
public static MethodReference NetworkReaderReadPackedInt32;
public static MethodReference NetworkReaderReadPacked64;
public static MethodReference NetworkReaderReadByte;
public static MethodReference NetworkWriterWritePacked32;
public static MethodReference NetworkWriterWritePackedUInt32;
public static MethodReference NetworkWriterWritePackedInt32;
public static MethodReference NetworkWriterWritePacked64;
public static MethodReference NetworkReadUInt16;
@ -1101,11 +1103,13 @@ static void SetupTargetTypes()
NetworkWriterWriteInt32 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int32Type);
NetworkWriterWriteInt16 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int16Type);
NetworkReaderReadPacked32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt32");
NetworkReaderReadPackedUInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt32");
NetworkReaderReadPackedInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedInt32");
NetworkReaderReadPacked64 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt64");
NetworkReaderReadByte = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadByte");
NetworkWriterWritePacked32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt32");
NetworkWriterWritePackedUInt32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt32");
NetworkWriterWritePackedInt32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedInt32");
NetworkWriterWritePacked64 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt64");
NetworkReadUInt16 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadUInt16");
@ -1182,8 +1186,8 @@ static void SetupReadFunctions()
{ stringType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadString") },
{ int64Type.FullName, NetworkReaderReadPacked64 },
{ uint64Type.FullName, NetworkReaderReadPacked64 },
{ int32Type.FullName, NetworkReaderReadPacked32 },
{ uint32Type.FullName, NetworkReaderReadPacked32 },
{ int32Type.FullName, NetworkReaderReadPackedInt32 },
{ uint32Type.FullName, NetworkReaderReadPackedUInt32 },
{ int16Type.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadInt16") },
{ uint16Type.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadUInt16") },
{ byteType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadByte") },
@ -1220,8 +1224,8 @@ static void SetupWriteFunctions()
{ stringType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", stringType) },
{ int64Type.FullName, NetworkWriterWritePacked64 },
{ uint64Type.FullName, NetworkWriterWritePacked64 },
{ int32Type.FullName, NetworkWriterWritePacked32 },
{ uint32Type.FullName, NetworkWriterWritePacked32 },
{ int32Type.FullName, NetworkWriterWritePackedInt32 },
{ uint32Type.FullName, NetworkWriterWritePackedUInt32 },
{ int16Type.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int16Type) },
{ uint16Type.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", uint16Type) },
{ byteType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", byteType) },

View File

@ -99,12 +99,12 @@ public IntegerMessage(int v)
public override void Deserialize(NetworkReader reader)
{
value = (int)reader.ReadPackedUInt32();
value = reader.ReadPackedInt32();
}
public override void Serialize(NetworkWriter writer)
{
writer.WritePackedUInt32((uint)value);
writer.WritePackedInt32(value);
}
}

View File

@ -57,6 +57,13 @@ public byte[] ReadBytesAndSize()
return null;
}
// zigzag decoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
public int ReadPackedInt32()
{
uint data = ReadPackedUInt32();
return (int)((data >> 1) ^ -(data & 1));
}
// http://sqlite.org/src4/doc/trunk/www/varint.wiki
// NOTE: big endian.
public uint ReadPackedUInt32()
@ -145,12 +152,12 @@ public Vector4 ReadVector4()
public Vector2Int ReadVector2Int()
{
return new Vector2Int((int)ReadPackedUInt32(), (int)ReadPackedUInt32());
return new Vector2Int(ReadPackedInt32(), ReadPackedInt32());
}
public Vector3Int ReadVector3Int()
{
return new Vector3Int((int)ReadPackedUInt32(), (int)ReadPackedUInt32(), (int)ReadPackedUInt32());
return new Vector3Int(ReadPackedInt32(), ReadPackedInt32(), ReadPackedInt32());
}
public Color ReadColor()

View File

@ -100,6 +100,13 @@ public void WriteBytesAndSize(byte[] buffer)
WriteBytesAndSize(buffer, 0, buffer != null ? buffer.Length : 0);
}
// zigzag encoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
public void WritePackedInt32(int i)
{
uint zigzagged = (uint)((i >> 31) ^ (i << 1));
WritePackedUInt32(zigzagged);
}
// http://sqlite.org/src4/doc/trunk/www/varint.wiki
public void WritePackedUInt32(uint value)
{
@ -216,15 +223,15 @@ public void Write(Vector4 value)
public void Write(Vector2Int value)
{
WritePackedUInt32((uint)value.x);
WritePackedUInt32((uint)value.y);
WritePackedInt32(value.x);
WritePackedInt32(value.y);
}
public void Write(Vector3Int value)
{
WritePackedUInt32((uint)value.x);
WritePackedUInt32((uint)value.y);
WritePackedUInt32((uint)value.z);
WritePackedInt32(value.x);
WritePackedInt32(value.y);
WritePackedInt32(value.z);
}
public void Write(Color value)

View File

@ -19,8 +19,8 @@ public class SyncListFloat : SyncList<float>
public class SyncListInt : SyncList<int>
{
protected override void SerializeItem(NetworkWriter writer, int item) => writer.WritePackedUInt32((uint)item);
protected override int DeserializeItem(NetworkReader reader) => (int)reader.ReadPackedUInt32();
protected override void SerializeItem(NetworkWriter writer, int item) => writer.WritePackedInt32(item);
protected override int DeserializeItem(NetworkReader reader) => reader.ReadPackedInt32();
}
public class SyncListUInt : SyncList<uint>

View File

@ -79,6 +79,42 @@ public void TestPackedUInt32()
Assert.That(reader.ReadPackedUInt32(), Is.EqualTo(uint.MaxValue));
}
[Test]
public void TestPackedInt32()
{
NetworkWriter writer = new NetworkWriter();
writer.WritePackedInt32(0);
writer.WritePackedInt32(234);
writer.WritePackedInt32(2284);
writer.WritePackedInt32(67821);
writer.WritePackedInt32(16777210);
writer.WritePackedInt32(16777219);
writer.WritePackedInt32(int.MaxValue);
writer.WritePackedInt32(-1);
writer.WritePackedInt32(-234);
writer.WritePackedInt32(-2284);
writer.WritePackedInt32(-67821);
writer.WritePackedInt32(-16777210);
writer.WritePackedInt32(-16777219);
writer.WritePackedInt32(int.MinValue);
NetworkReader reader = new NetworkReader(writer.ToArray());
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(0));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(234));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(2284));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(67821));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(16777210));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(16777219));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(int.MaxValue));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-1));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-234));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-2284));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-67821));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-16777210));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-16777219));
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(int.MinValue));
}
[Test]
public void TestPackedUInt64()
{