public void RunLclVarScenario_LoadAligned() { var left = Sse2.LoadAlignedVector128((Int32 *)(_dataTable.inArray1Ptr)); var right = Sse2.LoadAlignedVector128((Int32 *)(_dataTable.inArray2Ptr)); var result = Sse2.CompareGreaterThan(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunLclVarScenario_UnsafeRead() { var left = Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray1Ptr); var right = Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray2Ptr); var result = Sse2.CompareGreaterThan(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); var result = Sse2.CompareGreaterThan(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); }
public void RunBasicScenario_UnsafeRead() { var result = Sse2.CompareGreaterThan( Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray1Ptr), Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray2Ptr) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public void RunBasicScenario_LoadAligned() { var result = Sse2.CompareGreaterThan( Sse2.LoadAlignedVector128((Int16 *)(_dataTable.inArray1Ptr)), Sse2.LoadAlignedVector128((Int16 *)(_dataTable.inArray2Ptr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public void RunClsVarScenario() { var result = Sse2.CompareGreaterThan( _clsVar1, _clsVar2 ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); }
public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); var test = new SimpleBinaryOpTest__CompareGreaterThanInt32(); var result = Sse2.CompareGreaterThan(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public void RunStructLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); var result = Sse2.CompareGreaterThan(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); }
public static Vector128 <short> CreateAsciiMask(Vector128 <short> sourceValue) { Debug.Assert(Sse2.IsSupported); Vector128 <short> mask = Sse2.CompareLessThan(sourceValue, s_mask_UInt16_0x00); // Null, anything above short.MaxValue but less than or equal char.MaxValue mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_mask_UInt16_0x7E)); // Tilde '~', anything above the ASCII range return(mask); }
public static Vector4Int32 LessThanOrEqual(Vector4Int32Param1_3 left, Vector4Int32Param1_3 right) { if (Sse2.IsSupported) { Vector128 <int> mask = Vector128.Create(-1).AsInt32(); return(Sse2.Xor(Sse2.CompareGreaterThan(left, right), mask)); } return(LessThanOrEqual_Software(left, right)); }
public void RunLclVarScenario_LoadAligned() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); var op1 = Sse2.LoadAlignedVector128((Int16 *)(_dataTable.inArray1Ptr)); var op2 = Sse2.LoadAlignedVector128((Int16 *)(_dataTable.inArray2Ptr)); var result = Sse2.CompareGreaterThan(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); }
public void RunLclVarScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray1Ptr); var op2 = Unsafe.Read <Vector128 <Int16> >(_dataTable.inArray2Ptr); var result = Sse2.CompareGreaterThan(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); }
public static Vector4UInt32 LessThanOrEqual(Vector4UInt32Param1_3 left, Vector4UInt32Param1_3 right) { if (Sse2.IsSupported) { Vector128 <uint> mask = Vector128.Create(-1).AsUInt32(); Vector4UInt32 temp = Sse2.CompareGreaterThan(Sse2.Xor(left, ComparisonMask).AsInt32(), Sse2.Xor(right, ComparisonMask).AsInt32()).AsUInt32(); return(Sse2.Xor(mask, mask)); } return(LessThanOrEqual_Software(left, right)); }
public void RunLclVarScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var left = Sse2.LoadVector128((Int32 *)(_dataTable.inArray1Ptr)); var right = Sse2.LoadVector128((Int32 *)(_dataTable.inArray2Ptr)); var result = Sse2.CompareGreaterThan(left, right); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(left, right, _dataTable.outArrayPtr); }
public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); var result = Sse2.CompareGreaterThan( Unsafe.Read <Vector128 <Int32> >(_dataTable.inArray1Ptr), Unsafe.Read <Vector128 <Int32> >(_dataTable.inArray2Ptr) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public void RunBasicScenario_LoadAligned() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); var result = Sse2.CompareGreaterThan( Sse2.LoadAlignedVector128((Int32 *)(_dataTable.inArray1Ptr)), Sse2.LoadAlignedVector128((Int32 *)(_dataTable.inArray2Ptr)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); }
public static Vector128 <short> CreateAsciiMask(Vector128 <short> sourceValue) { Debug.Assert(Sse2.IsSupported); // Anything above short.MaxValue but less than or equal char.MaxValue // That's because anything between 32768 and 65535 (inclusive) will overflow and become negative. Vector128 <short> mask = Sse2.CompareLessThan(sourceValue, s_nullMaskInt16); // Anything above the ASCII range mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_maxAsciiCharacterMaskInt16)); return(mask); }
private Hit[] RayTraceAVXFaster(Ray ray) { Vector256 <double> dir = (Vector256 <double>)ray.Direction; Vector256 <double> vert0 = (Vector256 <double>)Vert0.Position; Vector256 <double> edge0to1 = (Vector256 <double>)Edge0to1; Vector256 <double> edge0to2 = (Vector256 <double>)Edge0to2; Vector256 <double> offset = Avx.Subtract((Vector256 <double>)ray.Origin, vert0); Vector256 <double> side1 = SIMDHelpers.Cross(offset, edge0to1); Vector256 <double> side2 = SIMDHelpers.Cross(dir, edge0to2); // Prepare all dot products Vector256 <double> uvTemp = Avx.Multiply(offset, side2); // u Vector256 <double> temp = Avx.Multiply(dir, side1); // v Vector256 <double> edge2Temp = Avx.Multiply(edge0to2, side1); Vector256 <double> distTemp = Avx.Multiply(edge0to1, side2); uvTemp = Avx.HorizontalAdd(uvTemp, temp); edge2Temp = Avx.HorizontalAdd(edge2Temp, edge2Temp); distTemp = Avx.HorizontalAdd(distTemp, distTemp); // Complete all dot products for SSE ops Vector128 <double> uvs = SIMDHelpers.Add2(uvTemp); Vector128 <double> dist = SIMDHelpers.Add2(edge2Temp); Vector128 <double> temp1 = SIMDHelpers.Add2(distTemp); Vector128 <double> temp2; // vec2 constants we'll be using later Vector128 <double> ones2 = SIMDHelpers.BroadcastScalar2(1D); Vector128 <double> zeroes2 = new Vector128 <double>(); // Reciprocal of distance along edge0to1 temp1 = Sse2.Divide(ones2, temp1); temp2 = Sse2.CompareOrdered(temp1, temp1); // Remove NaNs from the result, replaced with 0 Vector128 <double> distZeroed = Sse2.And(temp1, temp2); uvs = Sse2.Multiply(uvs, distZeroed); dist = Sse2.Multiply(dist, distZeroed); // compare uvs < 0 and > 1, dist < 0, jump out if any of those conditions are met temp1 = Sse2.CompareLessThan(uvs, zeroes2); temp2 = Mirror ? uvs : Sse3.HorizontalAdd(uvs, uvs); temp2 = Sse2.CompareGreaterThan(temp2, ones2); temp1 = Sse2.Or(temp1, temp2); temp2 = Sse2.CompareLessThan(dist, zeroes2); temp1 = Sse2.Or(temp1, temp2); if (!Avx.TestZ(temp1, temp1)) { return(default);
public void RunStructFldScenario_Load(SimpleBinaryOpTest__CompareGreaterThanInt16 testClass) { fixed(Vector128 <Int16> *pFld1 = &_fld1) fixed(Vector128 <Int16> *pFld2 = &_fld2) { var result = Sse2.CompareGreaterThan( Sse2.LoadVector128((Int16 *)(pFld1)), Sse2.LoadVector128((Int16 *)(pFld2)) ); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } }
unsafe private static void denoiseLineSse2(byte *pcurr, byte *pprev, byte *pnext, int cb) { byte *ip = pcurr, pp = pprev, np = pnext; nuint cnt = 0, end = (nuint)cb - (nuint)Vector128 <byte> .Count; var voffset = Vector128.Create((byte)0x80); var vthresh = Vector128.Create(denoiseThreshold); LoopTop: do { var vcurr = Sse2.LoadVector128(ip + cnt); var vprev = Sse2.LoadVector128(pp + cnt); var vnext = Sse2.LoadVector128(np + cnt); var vdiffp = Sse2.Or(Sse2.SubtractSaturate(vcurr, vprev), Sse2.SubtractSaturate(vprev, vcurr)); var vmaskp = Sse2.CompareEqual(Sse2.Max(vdiffp, vthresh), vthresh); var vdiffn = Sse2.Or(Sse2.SubtractSaturate(vcurr, vnext), Sse2.SubtractSaturate(vnext, vcurr)); var vmaskn = Sse2.CompareEqual(Sse2.Max(vdiffn, vthresh), vthresh); var vavgp = Sse2.Average(vcurr, vprev); var vavgn = Sse2.Average(vcurr, vnext); var voutval = Sse2.Average(HWIntrinsics.BlendVariable(vavgn, vavgp, vmaskp), HWIntrinsics.BlendVariable(vavgp, vavgn, vmaskn)); var voutmsk = Sse2.Or(vmaskp, vmaskn); voutval = Sse2.Average(voutval, HWIntrinsics.BlendVariable(voutval, Sse2.Average(vprev, vnext), Sse2.And(vmaskp, vmaskn))); var vcurrs = Sse2.Xor(vcurr, voffset).AsSByte(); var vprevs = Sse2.Xor(vprev, voffset).AsSByte(); var vnexts = Sse2.Xor(vnext, voffset).AsSByte(); var vsurlt = Sse2.And(Sse2.CompareGreaterThan(vcurrs, vprevs), Sse2.CompareGreaterThan(vcurrs, vnexts)); var vsurgt = Sse2.And(Sse2.CompareGreaterThan(vprevs, vcurrs), Sse2.CompareGreaterThan(vnexts, vcurrs)); voutmsk = Sse2.And(voutmsk, Sse2.Or(vsurlt, vsurgt).AsByte()); voutval = HWIntrinsics.BlendVariable(vcurr, voutval, voutmsk); Sse2.Store(ip + cnt, voutval); cnt += (nuint)Vector128 <byte> .Count; } while (cnt <= end); if (cnt < end + (nuint)Vector128 <byte> .Count) { cnt = end; goto LoopTop; } }
public void RunClsVarScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); fixed(Vector128 <SByte> *pClsVar1 = &_clsVar1) fixed(Vector128 <SByte> *pClsVar2 = &_clsVar2) { var result = Sse2.CompareGreaterThan( Sse2.LoadVector128((SByte *)(pClsVar1)), Sse2.LoadVector128((SByte *)(pClsVar2)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); } }
public void RunClassFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); fixed(Vector128 <Int16> *pFld1 = &_fld1) fixed(Vector128 <Int16> *pFld2 = &_fld2) { var result = Sse2.CompareGreaterThan( Sse2.LoadVector128((Int16 *)(pFld1)), Sse2.LoadVector128((Int16 *)(pFld2)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); } }
public static Vector128 <short> CreateEscapingMask_DefaultJavaScriptEncoderBasicLatin(Vector128 <short> sourceValue) { Debug.Assert(Sse2.IsSupported); Vector128 <short> mask = CreateEscapingMask_UnsafeRelaxedJavaScriptEncoder(sourceValue); mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x26)); // Ampersand '&' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x27)); // Apostrophe ''' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x2B)); // Plus sign '+' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x3C)); // Less Than Sign '<' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x3E)); // Greater Than Sign '>' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x60)); // Grave Access '`' mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_mask_UInt16_0x7E)); // Tilde '~', anything above the ASCII range return(mask); }
public static Vector128 <sbyte> CreateEscapingMask_UnsafeRelaxedJavaScriptEncoder(Vector128 <sbyte> sourceValue) { Debug.Assert(Sse2.IsSupported); // Anything in the control characters range (except 0x7F), and anything above sbyte.MaxValue but less than or equal byte.MaxValue // That's because anything between 128 and 255 (inclusive) will overflow and become negative. Vector128 <sbyte> mask = Sse2.CompareLessThan(sourceValue, s_spaceMaskSByte); mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_quotationMarkMaskSByte)); mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_reverseSolidusMaskSByte)); // Leftover control character in the ASCII range - 0x7F // Since we are dealing with sbytes, 0x7F is the only value that would meet this comparison. mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_tildeMaskSByte)); return(mask); }
public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); var test = new SimpleBinaryOpTest__CompareGreaterThanSByte(); fixed(Vector128 <SByte> *pFld1 = &test._fld1) fixed(Vector128 <SByte> *pFld2 = &test._fld2) { var result = Sse2.CompareGreaterThan( Sse2.LoadVector128((SByte *)(pFld1)), Sse2.LoadVector128((SByte *)(pFld2)) ); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); } }
public static Vector128 <short> CreateEscapingMask_UnsafeRelaxedJavaScriptEncoder(Vector128 <short> sourceValue) { Debug.Assert(Sse2.IsSupported); // Anything in the control characters range, and anything above short.MaxValue but less than or equal char.MaxValue // That's because anything between 32768 and 65535 (inclusive) will overflow and become negative. Vector128 <short> mask = Sse2.CompareLessThan(sourceValue, s_spaceMaskInt16); mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_quotationMarkMaskInt16)); mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_reverseSolidusMaskInt16)); // Anything above the ASCII range, and also including the leftover control character in the ASCII range - 0x7F // When this method is called with only ASCII data, 0x7F is the only value that would meet this comparison. // However, when called from "Default", the source could contain characters outside the ASCII range. mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_tildeMaskInt16)); return(mask); }
public void Step() { var shifted1 = Sse2.Shuffle(Positions, 0b10010011); var shifted2 = Sse2.Shuffle(Positions, 0b01001110); var shifted3 = Sse2.Shuffle(Positions, 0b00111001); // Calculate velocity additions var adds = Sse2.CompareGreaterThan(Positions, shifted1); adds = Sse2.Add(adds, Sse2.CompareGreaterThan(Positions, shifted2)); adds = Sse2.Add(adds, Sse2.CompareGreaterThan(Positions, shifted3)); // Calculate velocity subtractions adds = Sse2.Subtract(adds, Sse2.CompareLessThan(Positions, shifted1)); adds = Sse2.Subtract(adds, Sse2.CompareLessThan(Positions, shifted2)); adds = Sse2.Subtract(adds, Sse2.CompareLessThan(Positions, shifted3)); Velocities = Sse2.Add(Velocities, adds); Positions = Sse2.Add(Positions, Velocities); }
private static Vector128 <short> CreateEscapingMask(Vector128 <short> sourceValue) { Debug.Assert(Sse2.IsSupported); Vector128 <short> mask = Sse2.CompareLessThan(sourceValue, s_mask_UInt16_0x20); // Space ' ', anything in the control characters range mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x22)); // Quotation Mark '"' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x26)); // Ampersand '&' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x27)); // Apostrophe ''' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x2B)); // Plus sign '+' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x3C)); // Less Than Sign '<' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x3E)); // Greater Than Sign '>' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x5C)); // Reverse Solidus '\' mask = Sse2.Or(mask, Sse2.CompareEqual(sourceValue, s_mask_UInt16_0x60)); // Grave Access '`' mask = Sse2.Or(mask, Sse2.CompareGreaterThan(sourceValue, s_mask_UInt16_0x7E)); // Tilde '~', anything above the ASCII range return(mask); }
static bool TestSse2CompareGreaterThan() { if (Sse2.IsSupported) { const int expectedResult = 0b00; Vector128 <double> value1 = Vector128.Create(double.NaN, 1.0); Vector128 <double> value2 = Vector128.Create(0.0, 2.0); Vector128 <double> result = Sse2.CompareGreaterThan(value1, value2); int actualResult = Sse2.MoveMask(result); if (actualResult != expectedResult) { Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThan)}({value1}, {value2}) returned {Convert.ToString(actualResult, 2)}; expected {Convert.ToString(expectedResult, 2)}"); return(false); } } return(true); }
public static unsafe bool IsSorted_Sse41(int[] array) { if (array.Length < 2) { return(true); } if (!Sse41.IsSupported) //no SSE41 support { return(IsSorted_Simple2(array)); } int i = 0; fixed(int *ptr = &array[0]) { if (array.Length > 4) { for (; i < array.Length - 4; i += 4) // 8 for AVX2 and 16 for AVX512 { Vector128 <int> curr = Sse2.LoadVector128(ptr + i); Vector128 <int> next = Sse2.LoadVector128(ptr + i + 1); Vector128 <int> mask = Sse2.CompareGreaterThan(curr, next); if (!Sse41.TestAllZeros(mask, mask)) { return(false); } } } } for (; i < array.Length - 1; i++) { if (array[i] > array[i + 1]) { return(false); } } return(true); }