halve size of bitset for cpu compatibility

pull/5/head
Evan Hemsley 2019-12-22 21:13:54 -08:00
parent 1e73351b07
commit d6b96cd470
6 changed files with 77 additions and 77 deletions

View File

@ -2,28 +2,28 @@
namespace Encompass.Collections namespace Encompass.Collections
{ {
public static class BitSet1024Builder public static class BitSet512Builder
{ {
public static BitSet1024 Zeroes() public static BitSet512 Zeroes()
{ {
return new BitSet1024(Vector256Builder.Zeroes(), Vector256Builder.Zeroes(), Vector256Builder.Zeroes(), Vector256Builder.Zeroes()); return new BitSet512(Vector128Builder.Zeroes(), Vector128Builder.Zeroes(), Vector128Builder.Zeroes(), Vector128Builder.Zeroes());
} }
public static BitSet1024 Ones() public static BitSet512 Ones()
{ {
return new BitSet1024(Vector256Builder.Ones(), Vector256Builder.Ones(), Vector256Builder.Ones(), Vector256Builder.Ones()); return new BitSet512(Vector128Builder.Ones(), Vector128Builder.Ones(), Vector128Builder.Ones(), Vector128Builder.Ones());
} }
} }
public static class Vector256Builder public static class Vector128Builder
{ {
static readonly uint[] zeroes = new uint[8]; // max size of a Vector<T> is 8 uints static readonly uint[] zeroes = new uint[4]; // max size of a Vector<T> is 8 uints
static readonly uint[] ones = new uint[8] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue }; static readonly uint[] ones = new uint[4] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue };
static uint[] builderInts = new uint[8]; static uint[] builderInts = new uint[4];
private static void ResetBuilder() private static void ResetBuilder()
{ {
for (var i = 0; i < 8; i++) for (var i = 0; i < 4; i++)
{ {
builderInts[i] = 0; builderInts[i] = 0;
} }
@ -41,21 +41,21 @@ namespace Encompass.Collections
public static Vector<uint> Build(int index) public static Vector<uint> Build(int index)
{ {
if (index > 255) { throw new System.ArgumentOutOfRangeException(nameof(index)); } if (index > 127) { throw new System.ArgumentOutOfRangeException(nameof(index)); }
ResetBuilder(); ResetBuilder();
builderInts[index / 32] |= (uint)(1 << (index % 32)); builderInts[index / 32] |= (uint)(1 << (index % 32));
return new Vector<uint>(builderInts); return new Vector<uint>(builderInts);
} }
} }
public struct BitSet1024 public struct BitSet512
{ {
public Vector<uint> A { get; } public Vector<uint> A { get; }
public Vector<uint> B { get; } public Vector<uint> B { get; }
public Vector<uint> C { get; } public Vector<uint> C { get; }
public Vector<uint> D { get; } public Vector<uint> D { get; }
internal BitSet1024(Vector<uint> a, Vector<uint> b, Vector<uint> c, Vector<uint> d) internal BitSet512(Vector<uint> a, Vector<uint> b, Vector<uint> c, Vector<uint> d)
{ {
A = a; A = a;
B = b; B = b;
@ -63,38 +63,38 @@ namespace Encompass.Collections
D = d; D = d;
} }
public BitSet1024 And(BitSet1024 other) public BitSet512 And(BitSet512 other)
{ {
return new BitSet1024(A & other.A, B & other.B, C & other.C, D & other.D); return new BitSet512(A & other.A, B & other.B, C & other.C, D & other.D);
} }
public BitSet1024 Or(BitSet1024 other) public BitSet512 Or(BitSet512 other)
{ {
return new BitSet1024(A | other.A, B | other.B, C | other.C, D | other.D); return new BitSet512(A | other.A, B | other.B, C | other.C, D | other.D);
} }
public BitSet1024 Not() public BitSet512 Not()
{ {
return new BitSet1024(~A, ~B, ~C, ~D); return new BitSet512(~A, ~B, ~C, ~D);
} }
public BitSet1024 Set(int index) public BitSet512 Set(int index)
{ {
if (index < 256) if (index < 128)
{ {
return new BitSet1024(A | Vector256Builder.Build(index % 256), B, C, D); return new BitSet512(A | Vector128Builder.Build(index % 128), B, C, D);
}
else if (index < 256)
{
return new BitSet512(A, B | Vector128Builder.Build(index % 128), C, D);
}
else if (index < 384)
{
return new BitSet512(A, B, C | Vector128Builder.Build(index % 128), D);
} }
else if (index < 512) else if (index < 512)
{ {
return new BitSet1024(A, B | Vector256Builder.Build(index % 256), C, D); return new BitSet512(A, B, C, D | Vector128Builder.Build(index % 128));
}
else if (index < 768)
{
return new BitSet1024(A, B, C | Vector256Builder.Build(index % 256), D);
}
else if (index < 1024)
{
return new BitSet1024(A, B, C, D | Vector256Builder.Build(index % 256));
} }
else else
{ {
@ -102,23 +102,23 @@ namespace Encompass.Collections
} }
} }
public BitSet1024 UnSet(int index) public BitSet512 UnSet(int index)
{ {
if (index < 256) if (index < 128)
{ {
return new BitSet1024(A & ~Vector256Builder.Build(index % 256), B, C, D); return new BitSet512(A & ~Vector128Builder.Build(index % 256), B, C, D);
}
else if (index < 256)
{
return new BitSet512(A, B & ~Vector128Builder.Build(index % 256), C, D);
}
else if (index < 384)
{
return new BitSet512(A, B, C & ~Vector128Builder.Build(index % 256), D);
} }
else if (index < 512) else if (index < 512)
{ {
return new BitSet1024(A, B & ~Vector256Builder.Build(index % 256), C, D); return new BitSet512(A, B, C, D & ~Vector128Builder.Build(index % 256));
}
else if (index < 768)
{
return new BitSet1024(A, B, C & ~Vector256Builder.Build(index % 256), D);
}
else if (index < 1024)
{
return new BitSet1024(A, B, C, D & ~Vector256Builder.Build(index % 256));
} }
else else
{ {
@ -128,20 +128,20 @@ namespace Encompass.Collections
public bool Get(int index) public bool Get(int index)
{ {
var vectorIndex = index % 256; var vectorIndex = index % 128;
if (index < 256) if (index < 128)
{ {
return (A[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; return (A[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
} }
else if (index < 512) else if (index < 256)
{ {
return (B[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; return (B[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
} }
else if (index < 768) else if (index < 384)
{ {
return (C[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; return (C[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
} }
else if (index < 1024) else if (index < 512)
{ {
return (D[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; return (D[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
} }
@ -153,7 +153,7 @@ namespace Encompass.Collections
public bool AllTrue() public bool AllTrue()
{ {
for (var i = 0; i < 8; i++) for (var i = 0; i < 4; i++)
{ {
if (A[i] != uint.MaxValue) { return false; } if (A[i] != uint.MaxValue) { return false; }
if (B[i] != uint.MaxValue) { return false; } if (B[i] != uint.MaxValue) { return false; }
@ -165,7 +165,7 @@ namespace Encompass.Collections
public bool AllFalse() public bool AllFalse()
{ {
for (var i = 0; i < 8; i++) for (var i = 0; i < 4; i++)
{ {
if (A[i] != 0) { return false; } if (A[i] != 0) { return false; }
if (B[i] != 0) { return false; } if (B[i] != 0) { return false; }

View File

@ -7,7 +7,7 @@ namespace Encompass
{ {
internal class ComponentBitSet internal class ComponentBitSet
{ {
Dictionary<Entity, BitSet1024> entities = new Dictionary<Entity, BitSet1024>(); Dictionary<Entity, BitSet512> entities = new Dictionary<Entity, BitSet512>();
Dictionary<Type, int> TypeToIndex { get; } Dictionary<Type, int> TypeToIndex { get; }
public ComponentBitSet(Dictionary<Type, int> typeToIndex) public ComponentBitSet(Dictionary<Type, int> typeToIndex)
@ -27,7 +27,7 @@ namespace Encompass
public void AddEntity(Entity entity) public void AddEntity(Entity entity)
{ {
entities.Add(entity, BitSet1024Builder.Zeroes()); entities.Add(entity, BitSet512Builder.Zeroes());
} }
public void Set<TComponent>(Entity entity) where TComponent : struct, IComponent public void Set<TComponent>(Entity entity) where TComponent : struct, IComponent
@ -52,9 +52,9 @@ namespace Encompass
} }
} }
public BitSet1024 EntityBitArray(Entity entity) public BitSet512 EntityBitArray(Entity entity)
{ {
return entities.ContainsKey(entity) ? entities[entity] : BitSet1024Builder.Zeroes(); return entities.ContainsKey(entity) ? entities[entity] : BitSet512Builder.Zeroes();
} }
} }
} }

View File

@ -52,7 +52,7 @@ namespace Encompass
return Stores.ContainsKey(type) && Stores[type].Has(entity); return Stores.ContainsKey(type) && Stores[type].Has(entity);
} }
public BitSet1024 EntityBitArray(Entity entity) public BitSet512 EntityBitArray(Entity entity)
{ {
return ComponentBitSet.EntityBitArray(entity); return ComponentBitSet.EntityBitArray(entity);
} }

View File

@ -642,25 +642,25 @@ namespace Encompass
/// </summary> /// </summary>
internal void BuildEntityQuery() internal void BuildEntityQuery()
{ {
var withMask = BitSet1024Builder.Zeroes(); var withMask = BitSet512Builder.Zeroes();
foreach (var type in queryWithTypes) foreach (var type in queryWithTypes)
{ {
withMask = withMask.Set(componentUpdateManager.TypeToIndex[type]); withMask = withMask.Set(componentUpdateManager.TypeToIndex[type]);
} }
var withoutMask = BitSet1024Builder.Zeroes(); var withoutMask = BitSet512Builder.Zeroes();
foreach (var type in queryWithoutTypes) foreach (var type in queryWithoutTypes)
{ {
withoutMask = withoutMask.Set(componentUpdateManager.TypeToIndex[type]); withoutMask = withoutMask.Set(componentUpdateManager.TypeToIndex[type]);
} }
var pendingMask = BitSet1024Builder.Zeroes(); var pendingMask = BitSet512Builder.Zeroes();
foreach (var type in readPendingTypes) foreach (var type in readPendingTypes)
{ {
pendingMask = pendingMask.Set(componentUpdateManager.TypeToIndex[type]); pendingMask = pendingMask.Set(componentUpdateManager.TypeToIndex[type]);
} }
var existingMask = BitSet1024Builder.Zeroes(); var existingMask = BitSet512Builder.Zeroes();
foreach (var type in readTypes) foreach (var type in readTypes)
{ {
existingMask = existingMask.Set(componentUpdateManager.TypeToIndex[type]); existingMask = existingMask.Set(componentUpdateManager.TypeToIndex[type]);

View File

@ -6,13 +6,13 @@ namespace Encompass
{ {
internal struct EntitySetQuery internal struct EntitySetQuery
{ {
private BitSet1024 WithPendingMask { get; } private BitSet512 WithPendingMask { get; }
private BitSet1024 WithExistingMask { get; } private BitSet512 WithExistingMask { get; }
private BitSet1024 WithoutPendingMask { get; } private BitSet512 WithoutPendingMask { get; }
private BitSet1024 WithoutExistingMask { get; } private BitSet512 WithoutExistingMask { get; }
private BitSet1024 NotWithMask { get; } private BitSet512 NotWithMask { get; }
internal EntitySetQuery(BitSet1024 withPendingMask, BitSet1024 withExistingMask, BitSet1024 withoutPendingMask, BitSet1024 withoutExistingMask, BitSet1024 notWithMask) internal EntitySetQuery(BitSet512 withPendingMask, BitSet512 withExistingMask, BitSet512 withoutPendingMask, BitSet512 withoutExistingMask, BitSet512 notWithMask)
{ {
WithPendingMask = withPendingMask; WithPendingMask = withPendingMask;
WithExistingMask = withExistingMask; WithExistingMask = withExistingMask;

View File

@ -4,50 +4,50 @@ using NUnit.Framework;
namespace Tests namespace Tests
{ {
public class BitSet1024Test public class BitSet512Test
{ {
[Test] [Test]
public void Zeroes() public void Zeroes()
{ {
var bitSet = BitSet1024Builder.Zeroes(); var bitSet = BitSet512Builder.Zeroes();
bitSet.AllFalse().Should().BeTrue(); bitSet.AllFalse().Should().BeTrue();
} }
[Test] [Test]
public void Ones() public void Ones()
{ {
var bitSet = BitSet1024Builder.Ones(); var bitSet = BitSet512Builder.Ones();
bitSet.AllTrue().Should().BeTrue(); bitSet.AllTrue().Should().BeTrue();
} }
[Test] [Test]
public void Set() public void Set()
{ {
var bitSet = BitSet1024Builder.Zeroes().Set(5); var bitSet = BitSet512Builder.Zeroes().Set(5);
bitSet.AllFalse().Should().BeFalse(); bitSet.AllFalse().Should().BeFalse();
bitSet = BitSet1024Builder.Zeroes().Set(278); bitSet = BitSet512Builder.Zeroes().Set(132);
bitSet.AllFalse().Should().BeFalse(); bitSet.AllFalse().Should().BeFalse();
bitSet = BitSet1024Builder.Zeroes().Set(569); bitSet = BitSet512Builder.Zeroes().Set(268);
bitSet.AllFalse().Should().BeFalse(); bitSet.AllFalse().Should().BeFalse();
bitSet = BitSet1024Builder.Zeroes().Set(1023); bitSet = BitSet512Builder.Zeroes().Set(450);
bitSet.AllFalse().Should().BeFalse(); bitSet.AllFalse().Should().BeFalse();
} }
[Test] [Test]
public void UnSet() public void UnSet()
{ {
var bitSet = BitSet1024Builder.Ones().UnSet(562); var bitSet = BitSet512Builder.Ones().UnSet(285);
bitSet.Get(562).Should().BeFalse(); bitSet.Get(285).Should().BeFalse();
bitSet.Set(562).AllTrue().Should().BeTrue(); bitSet.Set(285).AllTrue().Should().BeTrue();
} }
[Test] [Test]
public void Get() public void Get()
{ {
var bitSet = BitSet1024Builder.Zeroes().Set(359); var bitSet = BitSet512Builder.Zeroes().Set(359);
bitSet.Get(359).Should().BeTrue(); bitSet.Get(359).Should().BeTrue();
bitSet.UnSet(359).AllFalse().Should().BeTrue(); bitSet.UnSet(359).AllFalse().Should().BeTrue();
} }
@ -55,7 +55,7 @@ namespace Tests
[Test] [Test]
public void Not() public void Not()
{ {
var bitSet = BitSet1024Builder.Ones().Not(); var bitSet = BitSet512Builder.Ones().Not();
bitSet.AllFalse().Should().BeTrue(); bitSet.AllFalse().Should().BeTrue();
} }
} }