Skip to content

Instantly share code, notes, and snippets.

@alyssaverkade
Created December 11, 2019 06:30
Show Gist options
  • Save alyssaverkade/cadd72ba1e9993e2c2e7aded29a38376 to your computer and use it in GitHub Desktop.
Save alyssaverkade/cadd72ba1e9993e2c2e7aded29a38376 to your computer and use it in GitHub Desktop.
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