Re: Calling kernel.dll from Mathematica
- To: mathgroup at smc.vnet.net
- Subject: [mg108583] Re: Calling kernel.dll from Mathematica
- From: Alexey Popkov <lehin.p at gmail.com>
- Date: Wed, 24 Mar 2010 04:42:45 -0500 (EST)
Todd, Interesting that I seem to have found a way to update the values. For this I call the method Get[]: freePhysicalMemoryFromWMI := (mo@Get[]; mo["FreePhysicalMemory"]); I have no idea where this is documented but observations have shown that it like works correctly. And it allows me to compare the effectiveness of two methods in terms of CPU load (I have a dual-core processor) by AbsoluteTiming. The following code compares the time required to obtain 10000 of actual values in two ways. Amazingly, the first method is 60 times slower than the second! It seems that in terms of performance with the frequent call working with the DLL is preferred. In[1]:= Needs["NETLink`"] query=NETNew["System.Management.ManagementObjectSearcher","SELECT * FROM Win32_OperatingSystem"]; resultCollection=query@Get[]; mo=First[NETObjectToExpression[resultCollection]]; freePhysicalMemoryFromWMI:=(mo@Get[];mo["FreePhysicalMemory"]); globalMemoryStatusEx=DefineDLLFunction["[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public class MEMORYSTATUSEX { public uint dwLength; public uint dwMemoryLoad; public ulong ullTotalPhys; public ulong ullAvailPhys; public ulong ullTotalPageFile; public ulong ullAvailPageFile; public ulong ullTotalVirtual; public ulong ullAvailVirtual; public ulong ullAvailExtendedVirtual; public MEMORYSTATUSEX() { this.dwLength = (uint) Marshal.SizeOf(typeof( MEMORYSTATUSEX )); } } [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool GlobalMemoryStatusEx( [In, Out] MEMORYSTATUSEX lpBuffer);"]; struct=NETNew["Wolfram.NETLink.DynamicDLLNamespace.DLLWrapper1+MEMORYSTATUSEX"]; freePhysicalMemoryFromDLL:=(globalMemoryStatusEx[struct];struct@ullAvailPhys ); Table[freePhysicalMemoryFromWMI,{10000}];//AbsoluteTiming Table[freePhysicalMemoryFromDLL,{10000}];//AbsoluteTiming Out[9]= {141.5937500,Null} Out[10]= {2.3750000,Null} Alexey Popkov 2010/3/24 Todd Gayley <tgayley at wolfram.com> > At 02:46 AM 3/20/2010, Alexey Popkov wrote: > >> Todd , >> >> Many thanks for the detailed response. Both methods are shown by you, very >> interesting. >> >> And thanks for sending a separate copy of the message directly to me: >> message appeared in the newsgroup is damaged, and part of the code from it >> does not work even after the correction of obvious damage. >> >> I have a question on the first method. As I understand, the function >> mo["FreePhysicalMemory"] >> will return the value corresponding to the time of creation of the first >> NETObject ('query'). Thus, it is not suitable for periodic calls on a >> regular basis. >> How can I get the actual value corresponding to the time of the call? Or >> how >> can I force updating of the values? >> > > > Alexey, > > Just re-do the entire call when you need the current values. Here is the > code packaged as a function: > > GetMemoryData[] := > NETBlock[ > Module[{query, mo}, > > query = NETNew["System.Management.ManagementObjectSearcher", > "SELECT * FROM Win32_OperatingSystem"]; > mo = First[NETObjectToExpression[query@Get[]]]; > (# -> mo[#])& /@ {"TotalVisibleMemorySize", "FreePhysicalMemory", > "TotalVirtualMemorySize"} > ] > ] > > > In[10]:= GetMemoryData[] > > Out[10]= {TotalVisibleMemorySize -> 3143336, FreePhysicalMemory -> 1124652, > TotalVirtualMemorySize -> 4444440} > > > > Todd Gayley > Wolfram Research > >