Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Calling kernel.dll from Mathematica

37 views
Skip to first unread message

Alexey Popkov

unread,
Mar 24, 2010, 5:33:55 AM3/24/10
to
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 <tga...@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
>
>


Alexey Popkov

unread,
Mar 28, 2010, 5:08:38 AM3/28/10
to
Todd,

Is there a straightforward way to determine which of the loaded NETTypes
corresponds to a function returned by DefineDLLFunction? Or the only way is
to use Definition[]?

Alexey Popkov


----- Original Message -----
From: "Todd Gayley" <tga...@wolfram.com>
To: "Alexey Popkov" <leh...@gmail.com>; <math...@smc.vnet.net>
Sent: Thursday, March 18, 2010 2:22 AM
Subject: Re: Calling kernel.dll from Mathematica
<...>

You can see that the
GlobalMemoryStatusEx function is in the context
Wolfram`NETLink`DynamicDLLNamespace`DLLWrapper1`,
which corresponds to a .NET class name of
Wolfram.NETLink.DynamicDLLNamespace.DLLWrapper1.
That is the class that was automatically created
to hold the GlobalMemoryStatusEx function. You
can also see that this is the created class name
by looking at LoadedNETTypes[]:

In[58]:= LoadedNETTypes[]

Out[58]= {NETType[Wolfram.NETLink.DynamicDLLNamespace.DLLWrapper1,1]}
<...>

Todd Gayley
Wolfram Research

Todd Gayley

unread,
Apr 1, 2010, 7:01:11 AM4/1/10
to
At 04:09 AM 3/28/2010, Alexey Popkov wrote:
>Todd,
>
>Is there a straightforward way to determine which of the loaded NETTypes
>corresponds to a function returned by DefineDLLFunction? Or the only way is
>to use Definition[]?


Alexey,

There isn't a particularly elegant way to do this. Looking at the
body of the function returned by DefineDLLFunction usually tells you
all you need to know. You could also call LoadedNETTypes[] before
DefineDLLFunction, and then call it afterwards, and use
Complement[after, before] to see what types were created by DefineDLLFunction.


Todd Gayley
Wolfram Research


0 new messages