Created
December 11, 2019 06:30
-
-
Save alyssaverkade/cadd72ba1e9993e2c2e7aded29a38376 to your computer and use it in GitHub Desktop.
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
using System; | |
using System.Collections; | |
using System.Runtime.Intrinsics.X86; | |
using System.Runtime.Intrinsics; | |
public struct BitMask | |
{ | |
private ushort mask; | |
BitMask(ushort mask_) => mask = mask_; | |
// Summary: | |
// Compares 16 bytes to see if they match a predicate, in parallel | |
unsafe BitMask matches(byte[] vec, byte predicate) | |
{ | |
fixed (byte* v = &vec[0]) { | |
var vector = Sse42.LoadVector128(v); | |
var pred = Vector128.Create(predicate); | |
return new BitMask( | |
(ushort)Sse42.MoveMask( | |
Sse42.CompareEqual(vector, pred) | |
) | |
); | |
} | |
} | |
} | |
public struct Group | |
{ | |
private Vector128<byte> vector; | |
private const ulong WIDTH = 16; // for SOME REASON we cannot do `unsafe { sizeof(Vector128<byte>) }` | |
public const byte EMPTY = 128; // 0b10000000 | |
public const byte DELETED = 254; // 0b11111111 | |
public const byte SENTINEL = 255; // 0b11111110 | |
// Summary: | |
// value: | |
// the value to which _all_ members of the group will be initialized to | |
Group(byte value) => vector = Vector128.Create(value); | |
// Parameters: | |
// slice: | |
// MUST be a length 16 byte array | |
// | |
// Exceptions: | |
// ArgumentException: Thrown if you do not pass a length 16 byte array | |
unsafe Group(byte[] slice) | |
{ | |
if (slice.Length != 16) { | |
throw new ArgumentException("Input MUST be length 16 >:("); | |
} | |
fixed (byte* v = &slice[0]) { | |
vector = Sse42.LoadVector128(v); | |
} | |
} | |
// Summary: | |
// Gets a bitmask of all the values in the vector | |
ushort BitMask() | |
{ | |
return (ushort)Sse2.MoveMask(vector); | |
} | |
// Summary: | |
// Here, Empty signifies that there are no matching | |
// elements contained in the group | |
bool IsEmpty() | |
{ | |
return this.BitMask() == 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment