using StgSharp.Math; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using static StgSharp.Optimization.CpuInfo; namespace StgSharp.Optimization { public static unsafe partial class SSE { public static m128 sqrtssM128Cache = new m128(); private static IntPtr sqrtssCodePointer; private static sqrtssDelegate sqrtssDele; private static byte[] sqrtssCodeBytes = new byte[] { 0x48,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // mov rax, [m128 location] 0xf3,0x0f,0x6f,0x00, // movqdu xmm0,xmmword ptr [rax] 0xf3,0x0f,0x51,0xc0, // sqrtss xmm0,xmm0 0xf3,0x0f,0x7f,0x00 // movdqu xmmword ptr [rax],xmm0 }; [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr VirtualAlloc( IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect ); [DllImport("kernel32")] private static extern bool VirtualFree( IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType ); private unsafe static void InitSqrtss() { var marshalPtr = Marshal.AllocHGlobal(32); var m128ptr = new IntPtr(16*((long)marshalPtr/16+1)); m128* sqrtssCachePointer = (m128*)m128ptr.ToPointer(); sqrtssM128Cache = *sqrtssCachePointer; byte[] sqrtssM128PointerBytes = BitConverter.GetBytes((ulong)sqrtssCachePointer); for (int i = 0; i < sqrtssM128PointerBytes.Length; i++) { sqrtssCodeBytes[2+i] = sqrtssCodeBytes[7-i]; } if (IntPtr.Size!=8) { throw new Exception("This SSE class support 64bits OS only presently!"); } sqrtssCodePointer = VirtualAlloc( IntPtr.Zero, new UIntPtr((uint)sqrtssCodeBytes.Length), AllocationType.COMMIT | AllocationType.RESERVE, MemoryProtection.EXECUTE_READWRITE ); Marshal.Copy(sqrtssCodeBytes, 0, sqrtssCodePointer, sqrtssCodeBytes.Length); sqrtssDele = (sqrtssDelegate)Marshal.GetDelegateForFunctionPointer(sqrtssCodePointer,typeof(sqrtssDelegate)); } public static float Sqrtss(float a) { sqrtssM128Cache.float0 = a; sqrtssDele(); return sqrtssM128Cache.float0; } } [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] internal delegate void sqrtssDelegate(); }