1. Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.

GPU-Z Shared Memory Class in C#

Discussion in 'Programming & Webmastering' started by Kreij, Apr 15, 2012.

  1. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    I wrote a C# class that reads the shared memory from GPU-Z.
    It doesn't use DLLImport or PInvoke (but it does require .Net 4), as it uses the new MemoryMappedFiles (MMF) namespace they added in 4.0

    The problem is that I can't think of anything useful to do with it that I can't get from just running GPU-Z. :/

    Any thought fellow coders and users of GPU-Z?

    I'll happily post the class source code when I nail down all the output requirements needed for any ideas you gents (and ladies) throw out.
  2. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    13,331 (6.31/day)
    Thanks Received:
    3,358
    Location:
    IA, USA
    Graph clockspeeds and memory usage.
    Crunching for Team TPU
  3. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    134 views and only one suggestion? (Thanks Ford)
    You guys suck at ideas as much as I do. :laugh:
  4. Mindweaver

    Mindweaver Moderato®™ Staff Member

    Joined:
    Apr 16, 2009
    Messages:
    5,143 (2.67/day)
    Thanks Received:
    2,650
    Location:
    Statesville, NC
    Yea.. I'm drawing blanks.. Oh course I've not had my full dose of caffeine yet... But I'm working on it...lol but right now.. I got nothing... :p
    Crunching for Team TPU
  5. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    I could always just toss the class code out and let people play with it.
    I just wanted to get some ideas what output formats (Arrays, Lists, etc.) might be useful for others and add them as methods to the class.

    Curently what I have is ..
    Code:
    void ReadSharedMemory() // Reads data from shared mem into classes
    List<KeyValuePair<string, string>> GetListOfRecords(); // Return a list of GPUZ_RECORD
    KeyValuePair<string, string>[] GetArrayOfRecords(); // Returns an array of GPUZ_RECORD
    
    List<GPUZ_SENSOR_RECORD> GetListOfSensors(); // Returns list of the sensor records.
    GPUZ_SENSOR_RECORD[] GetArrayOfSensors(); // Returns an array of sensor records.
    
    KeyValuePair<string, string> GetRecordByName (string name);
    GPUZ_SENSOR_RECORD GetSensorByName (string name);
    
    KeyValuePair<string, string> GetRecordByIndex (int index);
    GPUZ_SENSOR_RECORD GetSensorByIndex (int index);
    
    Anyone want to run a quick test on this stub program for me?
    Launch program, hit button. See if records print out (no sensor records, just board records)
    Try with GPU-Z running and not (It should detect if GPU-Z is running).
    You need .Net 4

    Thanks !!

    Attached Files:

    Last edited: Apr 18, 2012
  6. Munki

    Munki New Member

    Joined:
    Sep 13, 2008
    Messages:
    1,227 (0.57/day)
    Thanks Received:
    182
    Location:
    Metro Atlanta
    Without GPU-Z running:
    [​IMG]


    With GPU-Z Running:

    [​IMG]
    Kreij says thanks.
  7. TissueBox

    Joined:
    Mar 14, 2011
    Messages:
    79 (0.06/day)
    Thanks Received:
    38
    Not running:

    [​IMG]

    Running:

    [​IMG]
    Kreij says thanks.
  8. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    Thanks kids !!
    Munki sent me a PM pointing out my incorrect use of "it's" instead of "its" in the error message.
    Please feel free to trash me if you are a grammar nazi. :laugh: (it's been corrected in the code)

    If someone could try running it on a 32-bit box I would appreciate it. No need for screens, just let me know if you encounter any problems.

    @TissueBox : Welcome to P&W, our little corner of the world. Are you a coder?
  9. Munki

    Munki New Member

    Joined:
    Sep 13, 2008
    Messages:
    1,227 (0.57/day)
    Thanks Received:
    182
    Location:
    Metro Atlanta
    :laugh::laugh::laugh::laugh: I'm far from a grammar Nazi. I was born and raised in Georgia, my grammar is horrid :laugh:
  10. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    Sorry Munki ... I meant to say "if y'all a grammar nazi" :roll:

    I coded the class in a separate class file and removed the MessageBox error.
    I replaced it with an accessor (property called GPUZ_Running) so you can handle the fact GPU-Z may not be running yourself.

    Code:
    GPUZ_SHMEM shMem = new GPUZ_SHMEM();
    if (!shMem.GPUZ_Running)
    {
        // handle it however you want
    }
    else shMem.ReadSharedMem();
    
    Here's the class code if anyone want to take a look ...
    PHP:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    using System.IO;
    using System.IO.MemoryMappedFiles;

    namespace 
    WindowsFormsApplication1
    {
        public class 
    GPUZ_SHMEM
        
    {
            private const 
    int MAX_RECORDS 128;
            private 
    bool gPUZ_Running false;

            public class 
    GPUZ_SENSOR_RECORD
            
    {
                public 
    string name;
                public 
    string unit;
                public 
    UInt32 digits;
                public 
    Double value;
            };

            public class 
    GPUZ_SH_MEM
            
    {
                public 
    UInt32 version;
                public 
    volatile Int32 busy;
                public 
    UInt32 lastUpdate;
                public List<
    KeyValuePair<stringstring>> data = new List<KeyValuePair<stringstring>>(MAX_RECORDS);
                public List<
    GPUZ_SENSOR_RECORDsensors = new List<GPUZ_SENSOR_RECORD>(MAX_RECORDS);
            };

            public 
    GPUZ_SH_MEM shMem = new GPUZ_SH_MEM();

            public 
    GPUZ_SHMEM()
            {
                
    // Check to see if GPU-Z is running.
                
    foreach (Process p in Process.GetProcesses())
                {
                    if (
    p.ProcessName.Contains("GPU-Z")) gPUZ_Running true;
                }
            }

            public 
    bool GPUZ_Running get { return gPUZ_Running; } }

            public 
    void ReadSharedMemory()
            {

                
    string keyvalue;
                
    string nameunit;

                
    using (MemoryMappedFile mmf MemoryMappedFile.OpenExisting("GPUZShMem"))
                {
                    
    using (MemoryMappedViewStream mmvs mmf.CreateViewStream())
                    {
                        
    BinaryReader reader = new BinaryReader(mmvsEncoding.Unicode);

                        
    shMem.version reader.ReadUInt32();
                        
    shMem.busy reader.ReadInt32();
                        
    shMem.lastUpdate reader.ReadUInt32();

                        for (
    int i 0MAX_RECORDSi++)
                        {
                            
    // Remove any null values in the key array
                            
    key = new string(reader.ReadChars(256)).Trim('\0');
                            if (
    key.Contains("\0")) key key.Substring(0key.IndexOf("\0"));

                            
    // Remove any null values in the value array
                            
    value = new string(reader.ReadChars(256)).Trim('\0');
                            if (
    value.Contains("\0")) value value.Substring(0value.IndexOf("\0"));

                            
    // Only add List item if there is a valid key
                            
    if (key != String.Empty)
                            {
                                
    KeyValuePair<stringstringdataItem = new KeyValuePair<stringstring>(keyvalue);
                                
    shMem.data.Add(dataItem);
                            }
                        }

                        for (
    int i 0MAX_RECORDSi++)
                        {
                            
    // Remove any null values in the name array
                            
    name = new string(reader.ReadChars(256)).Trim('\0');
                            if (
    name.Contains("\0")) name name.Substring(0name.IndexOf("\0"));

                            
    // Remove any null values in the unit array
                            
    unit = new string(reader.ReadChars(8)).Trim('\0');
                            if (
    unit.Contains("\0")) unit unit.Substring(0unit.IndexOf('\0'));

                            
    // Only add List item if there is a valid name
                            
    if (name != String.Empty)
                            {
                                
    GPUZ_SENSOR_RECORD sensorItem = new GPUZ_SENSOR_RECORD();
                                
    sensorItem.name name;
                                
    sensorItem.unit unit;
                                
    sensorItem.digits reader.ReadUInt32();
                                
    sensorItem.value reader.ReadDouble();

                                
    shMem.sensors.Add(sensorItem);
                            }
                        }
                    }
                }
            }

            public List<
    KeyValuePair<stringstring>> GetListOfRecords()
            {
                return 
    shMem.data;
            }

            public 
    KeyValuePair<stringstring>[] GetArrayOfRecords()
            {
                
    KeyValuePair<stringstring>[] kvpArray;
                return 
    kvpArray shMem.data.ToArray();
            }

            public List<
    GPUZ_SENSOR_RECORDGetListOfSensors()
            {
                return 
    shMem.sensors;
            }

            public 
    GPUZ_SENSOR_RECORD[] GetArrayOfSensors()
            {
                
    GPUZ_SENSOR_RECORD[] sensorArrray;
                return 
    sensorArrray shMem.sensors.ToArray();
            }

            public 
    KeyValuePair<stringstringGetRecordByName(string name)
            {
                foreach (
    KeyValuePair<stringstringk in shMem.data)
                {
                    if (
    k.Key == name) return k;
                }

                
    // REturn a KVP with null values if name not found
                
    return new KeyValuePair<stringstring>(nullnull);
            }

            public 
    GPUZ_SENSOR_RECORD GetSensorByName(string name)
            {
                foreach (
    GPUZ_SENSOR_RECORD r in shMem.sensors)
                {
                    if (
    r.name == name) return r;
                }

                
    // Return a null class value if name not found
                
    return null;
            }

            public 
    KeyValuePair<stringstringGetRecordByIndex(int index)
            {
                if (
    index >= && index shMem.data.Count) return shMem.data[index];
                else return new 
    KeyValuePair<stringstring>(nullnull);

                
    // Returns a KVP with null values if index out of range
            
    }

            public 
    GPUZ_SENSOR_RECORD GetSensorByIndex(int index)
            {
                if (
    index >= && index shMem.sensors.Count) return shMem.sensors[index];
                else return 
    null;

                
    // Returns a null class value if index out of range.
            
    }
        }
    }

    It's C# code, I just used the php tags to give it a little color. :)
    As always, comments and suggestions appreciated !
    Last edited: Apr 18, 2012
    Munki says thanks.
  11. TissueBox

    Joined:
    Mar 14, 2011
    Messages:
    79 (0.06/day)
    Thanks Received:
    38
    Unfortunately, I am not - I'm more of a guinea pig :laugh:

    Looked at the "New Forum Posts" and decided to contribute something here :toast:
  12. crazyeyesreaper

    crazyeyesreaper Chief Broken Rig

    Joined:
    Mar 25, 2009
    Messages:
    8,131 (4.17/day)
    Thanks Received:
    2,745
    Location:
    04578
    hmm any chance you could set it to record and log memory usage kinda like fraps maybe? log min max avg memory usage i dont know lol maybe GPU-Z does that? i dont know drawing blanks just saying random shit that comes to mind
    Kreij says thanks.
  13. Aquinus

    Aquinus Resident Wat-man

    Joined:
    Jan 28, 2012
    Messages:
    5,953 (6.54/day)
    Thanks Received:
    1,920
    Location:
    Concord, NH
    Can GPU-Z run silently or minimized on start? If that can be done you could use the C# application to launch and close GPU-Z as needed.
    Kreij says thanks.
  14. Vinska

    Vinska

    Joined:
    Jul 23, 2011
    Messages:
    1,395 (1.27/day)
    Thanks Received:
    1,212
    Location:
    Kaunas, Lithuania
    Idea! How 'bout such feature: "alert me if some monitored value goes above/beyond *value* and/or stays above/beyond *value* for more than *time interval*." ?
    As far as I remember, GPU-Z can't do that.
    Last edited: Apr 26, 2012
    Kreij says thanks.
    Crunching for Team TPU
  15. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    GPU-Z can log everything if you check the log to file CheckBox. It puts it in a CSV text file.

    You can start GPU-Z minimized by going into the shortcuts properties and set the run dropdown to minimized. It would be a simple thing to launch GPU-Z from any app.

    That's a thought. A little, light wieght temp alarm utility. Any thoughts on how long it should read a "high" temp before alerting?

    One of the current issues is that if you open two instances of GPU-Z (say for crossfired cards) it still writes the data to the same shared memory and it's kind of hit or miss what card readings you are going to get. Maybe one of these days W1zz will add full multi-GPU functionality to GPU-Z
    Last edited: Apr 19, 2012
  16. Vinska

    Vinska

    Joined:
    Jul 23, 2011
    Messages:
    1,395 (1.27/day)
    Thanks Received:
    1,212
    Location:
    Kaunas, Lithuania
    I would suggest two modes:
    Monitor a user requested reading, with the ability to choose to trigger when going either below or above a user supplied value.
    First mode: alert as soon as it is below/above the threshold.
    Second mode: alert after it stays above/below the threshold longer than an interval which is also supplied by the user.
    When monitoring more than one thing, the modes should be set "per rule". for example, with two rules: "alert if the GPU temp stays above 75°C for more than 300 seconds & alert immediately, if it goes above 90°"
    or "immediately alert if the Vcore goes above 1.35V & alert if the GPU temp stays above 80°C for more than 60 seconds" and so on...

    P.S. The "below" setting could be useful, for example, to spot a fan failure.
    Last edited: Apr 26, 2012
    Kreij says thanks.
    Crunching for Team TPU
  17. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    Another Stub

    Here's another test stub.
    It's should read the GPU Temp (only, not #1 - #3) for a single card or a crossfire pair.
    You need to have two instances of GPU-Z running if using more than one card (and of course not have both instances pointing at the same card :D )
    It reads the shared mem every 500ms (this is somewhat problematic as it's still a bit of a crap shoot what card will be in the shared mem slot).

    Anyone have a dual-GPU card they could try it on?

    EDIT : No error checking to see if GPU-Z is running. It will throw an exception if no GPU-Z is available.

    Thanks !

    Attached Files:

  18. crazyeyesreaper

    crazyeyesreaper Chief Broken Rig

    Joined:
    Mar 25, 2009
    Messages:
    8,131 (4.17/day)
    Thanks Received:
    2,745
    Location:
    04578
    well i was thinking more like if the card switches to 3D clocks then have it record memory usage,

    GPU-Z tends to record constant makes it harder to pinpoint where Memory usage spikes im just being nitpicky tho as it would help pinpoint some of the harsher areas to test in games etc.

    Still pretty cool stuff your doing here Kreij
    Kreij says thanks.
  19. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    I assume you mean memory on the GPU?
    I have to look into this as only one of my corssfired cards shows dedicated and dynamic memory usage. Does the memory usage show up if you only have one card in?

    I'm just throwing out little test programs right now to get a handle on what I can and cannot do with the shared memory.
  20. crazyeyesreaper

    crazyeyesreaper Chief Broken Rig

    Joined:
    Mar 25, 2009
    Messages:
    8,131 (4.17/day)
    Thanks Received:
    2,745
    Location:
    04578
    its no problem Kreij
    and yea i ment Vram usage,

    example i dont care what vram usage is when lvl is loading in BF3 for instance, as my GPU clocks are idle at the time, same goes for SHogun 2 it takes 5-6 mins to load a battle, so if it could trigger logging ONLY during 3D clocks it would be amazing as aka run a benchmark we know how long it is, can use fraps for instance to test frame rates but at the same time, i can log just 3D vram usage on a second by second basis, might be way to hard to do, just something i find interesting.

    im only running 1 card right now and GPU-Z seems to be reporting memory usage properly
  21. Paciente8159 New Member

    Joined:
    Aug 15, 2011
    Messages:
    1 (0.00/day)
    Thanks Received:
    0
    I've made an overlay info display (small but practical) to run over a game or app on a corner of the screen.
    I can have realtime info of my gpu without leaving the game.

    Just an ideia..
  22. Vinska

    Vinska

    Joined:
    Jul 23, 2011
    Messages:
    1,395 (1.27/day)
    Thanks Received:
    1,212
    Location:
    Kaunas, Lithuania
    So, I finally got some time to relax from my studies, so I booted up window$.
    I checked how is that utility working... it doesn't look too well - monitors the max GPU clock reached.

    Yet, it looks promising, if ever going to be completed ;]

    I attached a screenshot:
    gpu-z_read.png
    Crunching for Team TPU
  23. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,881 (5.09/day)
    Thanks Received:
    5,615
    Location:
    Cheeseland (Wisconsin, USA)
    LOL ... didn't do that before. Something must have changed in 0.6.2

    I've put this project on hold at the moment.
    It's really unreliable for reading two cards, unfortunately. I'm hoping W1zz decides to add mutli-card support to the shared mem one of these days.
    Last edited: May 27, 2012
  24. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    13,331 (6.31/day)
    Thanks Received:
    3,358
    Location:
    IA, USA
    I noticed the NVIDIA Quadro driver (version 29#) had an option to install a WMI library. Has anyone taken a look into that?
    Crunching for Team TPU
  25. pspost New Member

    Joined:
    Jun 2, 2012
    Messages:
    2 (0.00/day)
    Thanks Received:
    0
    Hello!

    Please tell me why do we have to deal with GPU-Z and SharedMem interface? Why don't just read sensors as GPU-Z does? Is there GPU-Z source code? Or source code for reading sensors?

    I'm not familiar with this stuff (sensors reading) hence such a question I asked.

    Thanks.

    Paul

Currently Active Users Viewing This Thread: 1 (0 members and 1 guest)

Share This Page