I have the following code to find the minimum sbyte
value in an array. It is using System.Runtime.Intrinsics
to perform a SIMD min on chunks of the array, and then loops over the resulting vector to find the true minimum.
public static sbyte Min( sbyte[] array )
{
if( array.Length <= 0 )
return 0;
var length = array.Length;
var stepSize = Vector128<sbyte>.Count;
fixed ( sbyte* pStep = &array[ 0 ] )
{
var i = stepSize;
var minVector = Avx.LoadVector128( pStep );
for( ; i <= length - stepSize; i += stepSize )
minVector = Avx.Min( minVector, Avx.LoadVector128( pStep + i ) );
var _ = stackalloc sbyte[ stepSize ];
Avx.Store( _, minVector );
// Find min of minVector
var min = sbyte.MaxValue;
for( var j = 0; j < stepSize; j++ )
if( min > _[ j ] )
min = _[ j ];
// Evaluate remaining elements
if( i < length )
while( i < length )
{
if( min > pStep[ i ] )
min = pStep[ i ];
i++;
}
return min;
}
}
I feel like this is a slightly excessive amount of code, but seeing how this function is meant to handle arrays with lengths that can't be equally partitioned into a 128-bit register, I'm not sure if there's any cleaner way to do this.
I do intend to implement this method for all supported primitive types, but it seems like most of the code will just be duplicated.
var _
- what an unconventional variable name is this? o_O I'm also giving you a -1 for that because it's just impolite to use names like this one and expect people to understand your code. \$\endgroup\$_
is a terrible variable name, and is now used as a discard, which may create confusion. \$\endgroup\$