Wagnard CPU Core Analyser

Discussion in 'General Software and Applications' started by Wagnard, Apr 7, 2015.

  1. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
    Not yet, but will add in the future.


    EDIT: I just finished adding the number of threads and the Processor Queue Length. :D
     
    Last edited: Apr 27, 2015
  2. Elite3540

    Elite3540 Guest

    Messages:
    668
    Likes Received:
    1
    GPU:
    MSI GTX 970 GAMING 4G OC
    Nice program work as always Wagnard! :)

    You never cease to surprise us. =)
     
  3. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
    :bigsmile:
     
  4. mbk1969

    mbk1969 Ancient Guru

    Messages:
    15,601
    Likes Received:
    13,610
    GPU:
    GF RTX 4070

  5. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
  6. mbk1969

    mbk1969 Ancient Guru

    Messages:
    15,601
    Likes Received:
    13,610
    GPU:
    GF RTX 4070
  7. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
    Last edited: May 15, 2015
  8. mbk1969

    mbk1969 Ancient Guru

    Messages:
    15,601
    Likes Received:
    13,610
    GPU:
    GF RTX 4070
    Very simple routine which uses cool WinAPI functions for the performance counters query log file:
    - creates the performance counter query
    - adds (english) counters to the query
    - opens TSV log file for the query
    - updates log file periodically

    I added 11 counters and updated the log file with 500 ms interval - CPU usage was lower then 0.1%. And instead of TSV file you can specify CSV one. And TSV/CSV file can be analysed in spreadsheet app.

    Code:
    public void TraceSystem(int msInterval, string traceFile, string[] counters)
    {
        IntPtr hQuery = IntPtr.Zero;
        IntPtr hLog = IntPtr.Zero;
        IntPtr buffer = Marshal.AllocHGlobal(1024);
        try
        {
            int status = PdhOpenQuery(IntPtr.Zero, IntPtr.Zero, out hQuery);
            if (status != 0)
                throw new Win32Exception(status);
            char[] chararray;
            int added = 0;
            foreach (var counter in counters)
            {
                chararray = counter.ToCharArray();
                Marshal.Copy(chararray, 0, buffer, chararray.Length);
                Marshal.WriteInt16(buffer, chararray.Length*2, 0);
                IntPtr hCounter;
                status = PdhAddEnglishCounter(hQuery, buffer, IntPtr.Zero, out hCounter);
                if (status == 0)
                {
                    added++;
                }
                else
                {
                    var ee = new Win32Exception(status);
                }
            }
            if (0 == added)
                throw new ApplicationException("Failed to add performance counters to query");
            chararray = traceFile.ToCharArray();
            Marshal.Copy(chararray, 0, buffer, chararray.Length);
            Marshal.WriteInt16(buffer, chararray.Length*2, 0);
            uint dwLogType = PDH_LOG_TYPE_TSV;
            status = PdhOpenLog(buffer, PDH_LOG_WRITE_ACCESS|PDH_LOG_CREATE_ALWAYS, ref dwLogType, hQuery, 0, IntPtr.Zero, out hLog);
            if(status != 0)
                throw new Win32Exception(status);
            do
            {
                PdhUpdateLog(hLog, IntPtr.Zero);
                Thread.Sleep(msInterval);
            } while (true);
        }
        finally
        {
            if (hLog != IntPtr.Zero)
                PdhCloseLog(hLog, 0);
            if (hQuery != IntPtr.Zero)
                PdhCloseQuery(hQuery);
            if(buffer != IntPtr.Zero)
                Marshal.FreeHGlobal(buffer);
        }
    }
    
    
    [DllImport("Pdh.dll"), SuppressUnmanagedCodeSecurity]
    static extern int PdhOpenQuery([In] IntPtr szDataSource, [In]  IntPtr dwUserData, [Out] out IntPtr phQuery);
    
    [DllImport("Pdh.dll", CharSet=CharSet.Unicode), SuppressUnmanagedCodeSecurity]
    static extern int PdhAddEnglishCounter([In] IntPtr hQuery, [In] IntPtr szFullCounterPath, [In] IntPtr dwUserData, [Out] out IntPtr phCounter);
    
    [DllImport("Pdh.dll", CharSet=CharSet.Unicode), SuppressUnmanagedCodeSecurity]
    static extern int PdhOpenLog([In] IntPtr szLogFileName, [In] uint dwAccessFlags, [In, Out] ref uint dwLogType, [In] IntPtr hQuery, [In] uint dwMaxSize, [In] IntPtr szUserCaption, [Out] out IntPtr phLog);
    
    [DllImport("Pdh.dll"), SuppressUnmanagedCodeSecurity]
    static extern int PdhUpdateLog([In] IntPtr phLog, [In] IntPtr szUserString);
    
    [DllImport("Pdh.dll"), SuppressUnmanagedCodeSecurity]
    static extern int PdhCloseLog([In] IntPtr hLog, [In] uint dwFlags);
    
    [DllImport("Pdh.dll"), SuppressUnmanagedCodeSecurity]
    static extern int PdhCloseQuery([In] IntPtr hQuery);
    
    const uint PDH_LOG_READ_ACCESS      = 0x00010000;
    const uint PDH_LOG_WRITE_ACCESS     = 0x00020000;
    const uint PDH_LOG_UPDATE_ACCESS    = 0x00040000;
    const uint PDH_LOG_ACCESS_MASK      = 0x000F0000;
    
    const uint PDH_LOG_CREATE_NEW       = 0x00000001;
    const uint PDH_LOG_CREATE_ALWAYS    = 0x00000002;
    const uint PDH_LOG_OPEN_ALWAYS      = 0x00000003;
    const uint PDH_LOG_OPEN_EXISTING    = 0x00000004;
    const uint PDH_LOG_CREATE_MASK      = 0x0000000F;
    
    const uint PDH_LOG_OPT_USER_STRING  = 0x01000000;
    const uint PDH_LOG_OPT_CIRCULAR     = 0x02000000;
    const uint PDH_LOG_OPT_MAX_IS_BYTES = 0x04000000;
    const uint PDH_LOG_OPT_APPEND       = 0x08000000;
    const uint PDH_LOG_OPT_MASK         = 0x0F000000;
    
    const uint PDH_LOG_TYPE_UNDEFINED      = 0;
    const uint PDH_LOG_TYPE_CSV            = 1;
    const uint PDH_LOG_TYPE_TSV            = 2;
    const uint PDH_LOG_TYPE_TRACE_KERNEL   = 4;
    const uint PDH_LOG_TYPE_TRACE_GENERIC  = 5;
    const uint PDH_LOG_TYPE_PERFMON        = 6;
    const uint PDH_LOG_TYPE_SQL            = 7;
    const uint PDH_LOG_TYPE_BINARY         = 8;
    
     
    Last edited: May 28, 2015
  9. Watcher

    Watcher Ancient Guru

    Messages:
    2,697
    Likes Received:
    371
    GPU:
    Asus Dual RX6700 XT
    I'll have to give it a try. I'll need to brush up on the headers used at the top of each of the list to see exactly what they are indicating.
     
  10. Watcher

    Watcher Ancient Guru

    Messages:
    2,697
    Likes Received:
    371
    GPU:
    Asus Dual RX6700 XT
    Will these counters indicate the same information the " Core Analyzer " does

    How do you remove this counter when your done using it?

    Thanks
     

  11. mbk1969

    mbk1969 Ancient Guru

    Messages:
    15,601
    Likes Received:
    13,610
    GPU:
    GF RTX 4070
    You can pass to the routine any performance counters your system has in non-localized form.

    There is no need to remove the counter. You just close the query (I used the word 'session' for it - don`t know why, edited the post to replace 'session' with 'query').
     
  12. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
    Just to be sure I understand correctly, this is simply a way of logging the counter to a file or something like that?
    I'm not that good in C# and less in p-/invoke stuff. Its mostly a personal hobby.
     
  13. mbk1969

    mbk1969 Ancient Guru

    Messages:
    15,601
    Likes Received:
    13,610
    GPU:
    GF RTX 4070
    Exactly - logging specified counters to the log file. WinAPI functions do all work for you.
    And using CSV/TSV format allows to use spreadsheet application to analyse the data. There is also PERFMON format of log file which allows to view the log with Performance monitor or something like that.
     
  14. sfektsz

    sfektsz Guest

    Messages:
    48
    Likes Received:
    0
    GPU:
    NVIDIA GTX 770 2GB
    When you say 'Support up to 12 cores', is that a requirement, or a feature?
     
  15. Wagnard

    Wagnard Ancient Guru

    Messages:
    2,746
    Likes Received:
    519
    GPU:
    MSI Geforce GTX 1080
    Feature. Next version will be able to report any number of cores.

    EDIT:

    V3.2.0.0
    -Better CPU usage.
    -Can now detect any number of cores (not sure on Multi-CPU computer)
    -Line Colors in the Graphs can now be customized.
    -Fixes / Enhancements

    If someone can give me a screenshot on a multi-CPUs computer I would appreciate.
     
    Last edited: Jun 10, 2015

Share This Page