Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 43 additions & 24 deletions csharp/Platform.Collections/BitString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ namespace Platform.Collections
public class BitString : IEquatable<BitString>
{
private static readonly byte[][] _bitsSetIn16Bits;

/// <summary>
/// Minimum array length in words (64-bit) for Vector operations to be beneficial.
/// Based on performance analysis: 128 bits / 64 = 2 words minimum.
/// </summary>
private const int VectorMinThreshold = 2;

/// <summary>
/// Maximum array length in words (64-bit) for Vector operations to be beneficial.
/// Based on performance analysis: ~500,000 bits / 64 = ~7812 words maximum.
/// Beyond this size, cache effects make regular operations faster.
/// </summary>
private const int VectorMaxThreshold = 7812;

private long[] _array;
private long _length;
private long _minPositiveWord;
Expand Down Expand Up @@ -261,15 +275,11 @@ public BitString ParallelNot()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitString VectorNot()
{
if (!Vector.IsHardwareAccelerated || _array.LongLength >= int.MaxValue)
if (!ShouldUseVectorOperations())
{
return Not();
}
var step = Vector<long>.Count;
if (_array.Length < step)
{
return Not();
}
VectorNotLoop(_array, step, 0, _array.Length);
MarkBordersAsAllBitsSet();
TryShrinkBorders();
Expand All @@ -294,7 +304,7 @@ public BitString ParallelVectorNot()
{
return VectorNot();
}
if (!Vector.IsHardwareAccelerated)
if (!ShouldUseVectorOperations())
{
return ParallelNot();
}
Expand Down Expand Up @@ -431,15 +441,11 @@ public BitString ParallelAnd(BitString other)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitString VectorAnd(BitString other)
{
if (!Vector.IsHardwareAccelerated || _array.LongLength >= int.MaxValue)
if (!ShouldUseVectorOperations())
{
return And(other);
}
var step = Vector<long>.Count;
if (_array.Length < step)
{
return And(other);
}
EnsureBitStringHasTheSameSize(other, nameof(other));
GetCommonOuterBorders(this, other, out int from, out int to);
VectorAndLoop(_array, other._array, step, from, to + 1);
Expand Down Expand Up @@ -470,7 +476,7 @@ public BitString ParallelVectorAnd(BitString other)
{
return VectorAnd(other);
}
if (!Vector.IsHardwareAccelerated)
if (!ShouldUseVectorOperations())
{
return ParallelAnd(other);
}
Expand Down Expand Up @@ -612,15 +618,11 @@ public BitString ParallelOr(BitString other)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitString VectorOr(BitString other)
{
if (!Vector.IsHardwareAccelerated || _array.LongLength >= int.MaxValue)
if (!ShouldUseVectorOperations())
{
return Or(other);
}
var step = Vector<long>.Count;
if (_array.Length < step)
{
return Or(other);
}
EnsureBitStringHasTheSameSize(other, nameof(other));
GetCommonOuterBorders(this, other, out int from, out int to);
VectorOrLoop(_array, other._array, step, from, to + 1);
Expand Down Expand Up @@ -651,7 +653,7 @@ public BitString ParallelVectorOr(BitString other)
{
return VectorOr(other);
}
if (!Vector.IsHardwareAccelerated)
if (!ShouldUseVectorOperations())
{
return ParallelOr(other);
}
Expand Down Expand Up @@ -793,15 +795,11 @@ public BitString ParallelXor(BitString other)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitString VectorXor(BitString other)
{
if (!Vector.IsHardwareAccelerated || _array.LongLength >= int.MaxValue)
if (!ShouldUseVectorOperations())
{
return Xor(other);
}
var step = Vector<long>.Count;
if (_array.Length < step)
{
return Xor(other);
}
EnsureBitStringHasTheSameSize(other, nameof(other));
GetCommonOuterBorders(this, other, out int from, out int to);
VectorXorLoop(_array, other._array, step, from, to + 1);
Expand Down Expand Up @@ -832,7 +830,7 @@ public BitString ParallelVectorXor(BitString other)
{
return VectorXor(other);
}
if (!Vector.IsHardwareAccelerated)
if (!ShouldUseVectorOperations())
{
return ParallelXor(other);
}
Expand Down Expand Up @@ -891,6 +889,27 @@ static private void VectorXorLoop(long[] array, long[] otherArray, int step, int
array[i] ^= otherArray[i];
}
}

/// <summary>
/// <para>
/// Determines whether Vector operations should be used based on hardware acceleration availability
/// and optimal size thresholds determined through performance analysis.
/// </para>
/// <para></para>
/// </summary>
/// <returns>
/// <para>True if Vector operations are likely to be faster than regular operations, false otherwise.</para>
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool ShouldUseVectorOperations()
{
return Vector.IsHardwareAccelerated &&
_array.LongLength < int.MaxValue &&
_array.Length >= VectorMinThreshold &&
_array.Length <= VectorMaxThreshold;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void RefreshBordersByWord(long wordIndex)
{
Expand Down
Loading
Loading