public static bool Equal(Vector128 <float> vector1, Vector128 <float> vector2) { // This implementation is based on the DirectX Math Library XMVector4Equal method // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl if (AdvSimd.Arm64.IsSupported) { Vector128 <uint> vResult = AdvSimd.CompareEqual(vector1, vector2).AsUInt32(); Vector64 <byte> vResult0 = vResult.GetLower().AsByte(); Vector64 <byte> vResult1 = vResult.GetUpper().AsByte(); Vector64 <byte> vTemp10 = AdvSimd.Arm64.ZipLow(vResult0, vResult1); Vector64 <byte> vTemp11 = AdvSimd.Arm64.ZipHigh(vResult0, vResult1); Vector64 <ushort> vTemp21 = AdvSimd.Arm64.ZipHigh(vTemp10.AsUInt16(), vTemp11.AsUInt16()); return(vTemp21.AsUInt32().GetElement(1) == 0xFFFFFFFF); } else if (Sse.IsSupported) { return(Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) == 0); } else { // Redundant test so we won't prejit remainder of this method on platforms without AdvSimd. throw new PlatformNotSupportedException(); } }
static unsafe int Main(string[] args) { int testResult = Pass; if (Sse.IsSupported) { using (TestTable <float> floatTable = new TestTable <float>(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) { var vf1 = Unsafe.Read <Vector128 <float> >(floatTable.inArray1Ptr); var vf2 = Unsafe.Read <Vector128 <float> >(floatTable.inArray2Ptr); var vf3 = Sse.CompareNotEqual(vf1, vf2); Unsafe.Write(floatTable.outArrayPtr, vf3); if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x != y) ? -1 : 0))) { Console.WriteLine("SSE CompareNotEqual failed on float:"); foreach (var item in floatTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } } } return(testResult); }
public void RunStructFldScenario(SimpleBinaryOpTest__CompareNotEqualSingle testClass) { var result = Sse.CompareNotEqual(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); }
public void RunClassFldScenario() { var result = Sse.CompareNotEqual(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); }
public static bool SequenceEqual_Sse(float[] array1, float[] array2) { if (array1.Length != array2.Length) { return(false); } if (array1.Length == 0) { return(true);//SequenceEqual_Soft(array1, array2, 0); } int i = 0; fixed(float *ptr1 = &array1[0]) fixed(float *ptr2 = &array2[0]) { if (array1.Length < 4) { return(SequenceEqual_Soft(ptr1, ptr2, 0, array1.Length)); } for (; i <= array1.Length - 4; i += 4) { Vector128 <float> vec1 = Sse.LoadVector128(ptr1 + i); Vector128 <float> vec2 = Sse.LoadVector128(ptr2 + i); var ce = Sse.MoveMask(Sse.CompareNotEqual(vec1, vec2)) == 0; if (!ce) { return(false); } } return(SequenceEqual_Soft(ptr1, ptr2, i, array1.Length)); } }
public void RunClassLclFldScenario() { var test = new SimpleBinaryOpTest__CompareNotEqualSingle(); var result = Sse.CompareNotEqual(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public void RunStructLclFldScenario() { var test = TestStruct.Create(); var result = Sse.CompareNotEqual(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public static Vector4F Inequality(Vector4FParam1_3 left, Vector4FParam1_3 right) { if (Sse.IsSupported) { return(Sse.CompareNotEqual(left, right)); } return(Inequality_Software(left, right)); }
public static Vector128 <float> CompareNotEqual(Vector4FParam1_3 left, Vector4FParam1_3 right) { if (Sse.IsSupported) { return(Sse.CompareNotEqual(left, right)); } return(CompareNotEqual_Software(left, right)); }
public void RunLclVarScenario_UnsafeRead() { var left = Unsafe.Read <Vector128 <Single> >(_dataTable.inArray1Ptr); var right = Unsafe.Read <Vector128 <Single> >(_dataTable.inArray2Ptr); var result = Sse.CompareNotEqual(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunLclVarScenario_LoadAligned() { var left = Sse.LoadAlignedVector128((Single *)(_dataTable.inArray1Ptr)); var right = Sse.LoadAlignedVector128((Single *)(_dataTable.inArray2Ptr)); var result = Sse.CompareNotEqual(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); var result = Sse.CompareNotEqual(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); }
public void RunStructLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); var result = Sse.CompareNotEqual(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public void RunClsVarScenario() { var result = Sse.CompareNotEqual( _clsVar1, _clsVar2 ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); }
public void RunBasicScenario_UnsafeRead() { var result = Sse.CompareNotEqual( Unsafe.Read <Vector128 <Single> >(_dataTable.inArray1Ptr), Unsafe.Read <Vector128 <Single> >(_dataTable.inArray2Ptr) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public void RunBasicScenario_LoadAligned() { var result = Sse.CompareNotEqual( Sse.LoadAlignedVector128((Single *)(_dataTable.inArray1Ptr)), Sse.LoadAlignedVector128((Single *)(_dataTable.inArray2Ptr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public void RunLclVarScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read <Vector128 <Single> >(_dataTable.inArray1Ptr); var op2 = Unsafe.Read <Vector128 <Single> >(_dataTable.inArray2Ptr); var result = Sse.CompareNotEqual(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); }
public void RunLclVarScenario_LoadAligned() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); var op1 = Sse.LoadAlignedVector128((Single *)(_dataTable.inArray1Ptr)); var op2 = Sse.LoadAlignedVector128((Single *)(_dataTable.inArray2Ptr)); var result = Sse.CompareNotEqual(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); }
public void RunLclVarScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var left = Sse.LoadVector128((Single *)(_dataTable.inArray1Ptr)); var right = Sse.LoadVector128((Single *)(_dataTable.inArray2Ptr)); var result = Sse.CompareNotEqual(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunStructLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); var result = Sse.CompareNotEqual( Sse.LoadVector128((Single *)(&test._fld1)), Sse.LoadVector128((Single *)(&test._fld2)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public void RunStructFldScenario_Load(SimpleBinaryOpTest__CompareNotEqualSingle testClass) { fixed(Vector128 <Single> *pFld1 = &_fld1) fixed(Vector128 <Single> *pFld2 = &_fld2) { var result = Sse.CompareNotEqual( Sse.LoadVector128((Single *)(pFld1)), Sse.LoadVector128((Single *)(pFld2)) ); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } }
public void RunClassFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); fixed(Vector128 <Single> *pFld1 = &_fld1) fixed(Vector128 <Single> *pFld2 = &_fld2) { var result = Sse.CompareNotEqual( Sse.LoadVector128((Single *)(pFld1)), Sse.LoadVector128((Single *)(pFld2)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); } }
public static bool SequenceEqual_Sse_aligned(float[] array1, float[] array2) { if (array1.Length != array2.Length) { return(false); } if (array1.Length == 0) { return(true);//SequenceEqual_Soft(array1, array2, 0); } int i = 0; fixed(float *ptr1 = &array1[0]) fixed(float *ptr2 = &array2[0]) { var aligned1 = (float *)(((ulong)ptr1 + 31UL) & ~31UL); var aligned2 = (float *)(((ulong)ptr2 + 31UL) & ~31UL); var pos1 = (int)(aligned1 - ptr1); var pos2 = (int)(aligned2 - ptr2); var pos = Math.Max(pos1, pos2); if (array1.Length < 4) { return(SequenceEqual_Soft(ptr1, ptr2, 0, array1.Length)); } if (pos > 0) { SequenceEqual_Soft(ptr1, ptr2, 0, pos); i = pos; } for (; i <= array1.Length - 4; i += 4) { Vector128 <float> vec1 = Sse.LoadVector128(ptr1 + i); Vector128 <float> vec2 = Sse.LoadVector128(ptr2 + i); var ce = Sse.MoveMask(Sse.CompareNotEqual(vec1, vec2)) == 0; if (!ce) { return(false); } } return(SequenceEqual_Soft(ptr1, ptr2, i, array1.Length)); } }
public static m32 NotEqual(f32 lhs, f32 rhs) => Sse.CompareNotEqual(lhs, rhs).AsInt32();
public static Vector128 <float> _mm_cmpneq_ps(Vector128 <float> left, Vector128 <float> right) { return(Sse.CompareNotEqual(left, right)); }
private static unsafe int CalculateDistance(string sourceString, int sourceLength, string targetString, int targetLength, int startIndex) { var arrayPool = ArrayPool <int> .Shared; var pooledArray = arrayPool.Rent(targetLength); Span <int> previousRow = pooledArray; ReadOnlySpan <char> source = sourceString.AsSpan().Slice(startIndex, sourceLength); ReadOnlySpan <char> target = targetString.AsSpan().Slice(startIndex, targetLength); //ArrayPool values are sometimes bigger than allocated, let's trim our span to exactly what we use previousRow = previousRow.Slice(0, targetLength); fixed(char *targetPtr = target) fixed(char *srcPtr = source) fixed(int *previousRowPtr = previousRow) { FillRow(previousRowPtr, targetLength); var rowIndex = 0; for (; rowIndex < sourceLength - 3; rowIndex += 4) { var diag = Vector128.Create(rowIndex); var left = Vector128.Create(rowIndex + 1); var sourceV = Sse42.ConvertToVector128Int32((short *)(srcPtr + rowIndex)); var targetV = Vector128 <int> .Zero; var one = Vector128.Create(1); // First 3 iterations fills the vector var shift = Vector128.CreateScalar(-1); for (int columnIndex = 0; columnIndex < 4; columnIndex++) { // Shift in the next character targetV = Sse42.ShiftLeftLogical128BitLane(targetV, 4); targetV = Sse42.Insert(targetV, (short)targetPtr[columnIndex], 0); //left = Sse42.Insert(left, rowIndex + columnIndex + 1, (byte)columnIndex); var leftValue = Vector128.Create(rowIndex + columnIndex + 1); left = Sse42.Or(Sse42.And(shift, leftValue), left); shift = Sse42.ShiftLeftLogical128BitLane(shift, 4); // compare source to target // alternativ, compare equal and OR with One var match = Sse.CompareNotEqual(sourceV.AsSingle(), targetV.AsSingle()); var next = Sse42.Subtract(diag, match.AsInt32()); // Create next diag which is current up var up = Sse42.ShiftLeftLogical128BitLane(left, 4); up = Sse42.Insert(up, previousRowPtr[columnIndex], 0); var tmp = Sse42.Add(Sse42.Min(left, up), one); next = Sse42.Min(next, tmp); left = next; diag = up; } previousRowPtr[0] = Sse42.Extract(left, 3); for (int columnIndex = 4; columnIndex < targetLength; columnIndex++) { // Shift in the next character targetV = Sse42.ShiftLeftLogical128BitLane(targetV, 4); targetV = Sse42.Insert(targetV, (short)targetPtr[columnIndex], 0); // compare source to target // alternativ, compare equal and OR with One var match = Sse42.CompareNotEqual(sourceV.AsSingle(), targetV.AsSingle()); var next = Sse42.Subtract(diag, match.AsInt32()); // Create next diag which is current up var up = Sse42.ShiftLeftLogical128BitLane(left, 4); up = Sse42.Insert(up, previousRowPtr[columnIndex], 0); var tmp = Sse42.Add(Sse42.Min(left, up), one); next = Sse42.Min(next, tmp); left = next; diag = up; // Store one value previousRowPtr[columnIndex - 3] = Sse42.Extract(next, 3); } // Finish with last 3 items, dont read any more chars just extract them for (int i = targetLength - 3; i < targetLength; i++) { // Shift in the next character targetV = Sse42.ShiftLeftLogical128BitLane(targetV, 4); // compare source to target // alternativ, compare equal and OR with One var match = Sse.CompareNotEqual(sourceV.AsSingle(), targetV.AsSingle()); var next = Sse42.Subtract(diag, match.AsInt32()); // Create next diag which is current up var up = Sse42.ShiftLeftLogical128BitLane(left, 4); var tmp = Sse42.Add(Sse42.Min(left, up), one); next = Sse42.Min(next, tmp); left = next; diag = up; // Store one value previousRowPtr[i] = Sse42.Extract(next, 3); } #if DEBUG if (true) { Console.Write("prev values for row {0}:", rowIndex); for (int i = 0; i < targetLength; ++i) { Console.Write("{0} ", previousRow[i]); } Console.WriteLine(); } #endif } //Calculate Single Rows for (; rowIndex < sourceLength; rowIndex++) { var lastSubstitutionCost = rowIndex; var lastInsertionCost = rowIndex + 1; var sourcePrevChar = source[rowIndex]; #if DEBUG Console.Write("prev values for row {0}:", rowIndex); for (int i = 0; i < targetLength; ++i) { Console.Write("{0} ", previousRow[i]); } Console.WriteLine(); #endif CalculateRow(previousRowPtr, targetPtr, targetLength, sourcePrevChar, lastInsertionCost, lastSubstitutionCost); } } var result = previousRow[targetLength - 1]; arrayPool.Return(pooledArray); return(result); }
public static bool NotEqual(Vector128 <float> vector1, Vector128 <float> vector2) { Debug.Assert(Sse.IsSupported); return(Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) != 0); }
public static Vector128 <float> op_Inequality(Vector128 <float> left, Vector128 <float> right) => Sse.CompareNotEqual(left, right);