how to determine CPU cache size in .NET?

后端 未结 4 1032
谎友^
谎友^ 2021-01-13 10:32

I would like to know if there is a way to determine CPU cache size in managed code?

I am writing a Strassen\'s algorithm for matrix multiplication in C# and would li

相关标签:
4条回答
  • 2021-01-13 11:04

    Try this code

    using System.Management;
    
    uint32 cachsize;
    public void CPUSpeed()
    {
      using(ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
      {
        cachsize = (uint)(Mo["L2CacheSize"]);
      }
    }
    

    I get it from Here

    0 讨论(0)
  • 2021-01-13 11:09

    is this what you are looking for? The Win32_Processor class features L2CacheSize and L3CacheSize members.

    0 讨论(0)
  • 2021-01-13 11:18
        using System;
        using System.Runtime.InteropServices;
    
        class Processor
        {
            [DllImport("kernel32.dll")]
            public static extern int GetCurrentThreadId();
    
            //[DllImport("kernel32.dll")]
            //public static extern int GetCurrentProcessorNumber();
    
            [StructLayout(LayoutKind.Sequential, Pack = 4)]
            private struct GROUP_AFFINITY
            {
                public UIntPtr Mask;
    
                [MarshalAs(UnmanagedType.U2)]
                public ushort Group;
    
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U2)]
                public ushort[] Reserved;
            }
    
            [DllImport("kernel32", SetLastError = true)]
            private static extern Boolean SetThreadGroupAffinity(IntPtr hThread, ref GROUP_AFFINITY GroupAffinity, ref GROUP_AFFINITY PreviousGroupAffinity);
    
            [StructLayout(LayoutKind.Sequential)]
            public struct PROCESSORCORE
            {
                public byte Flags;
            };
    
            [StructLayout(LayoutKind.Sequential)]
            public struct NUMANODE
            {
                public uint NodeNumber;
            }
    
            public enum PROCESSOR_CACHE_TYPE
            {
                CacheUnified,
                CacheInstruction,
                CacheData,
                CacheTrace
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct CACHE_DESCRIPTOR
            {
                public byte Level;
                public byte Associativity;
                public ushort LineSize;
                public uint Size;
                public PROCESSOR_CACHE_TYPE Type;
            }
    
            [StructLayout(LayoutKind.Explicit)]
            public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION
            {
                [FieldOffset(0)]
                public PROCESSORCORE ProcessorCore;
                [FieldOffset(0)]
                public NUMANODE NumaNode;
                [FieldOffset(0)]
                public CACHE_DESCRIPTOR Cache;
                [FieldOffset(0)]
                private UInt64 Reserved1;
                [FieldOffset(8)]
                private UInt64 Reserved2;
            }
    
            public enum LOGICAL_PROCESSOR_RELATIONSHIP
            {
                RelationProcessorCore,
                RelationNumaNode,
                RelationCache,
                RelationProcessorPackage,
                RelationGroup,
                RelationAll = 0xffff
            }
    
            public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION
            {
    #pragma warning disable 0649
                public UIntPtr ProcessorMask;
                public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
                public SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION ProcessorInformation;
    #pragma warning restore 0649
            }
    
            [DllImport(@"kernel32.dll", SetLastError = true)]
            public static extern bool GetLogicalProcessorInformation(IntPtr Buffer, ref uint ReturnLength);
    
            private const int ERROR_INSUFFICIENT_BUFFER = 122;
    
            private static SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] _logicalProcessorInformation = null;
    
            public static SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] LogicalProcessorInformation
            {
                get
                {
                    if (_logicalProcessorInformation != null)
                        return _logicalProcessorInformation;
    
                    uint ReturnLength = 0;
    
                    GetLogicalProcessorInformation(IntPtr.Zero, ref ReturnLength);
    
                    if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
                    {
                        IntPtr Ptr = Marshal.AllocHGlobal((int)ReturnLength);
                        try
                        {
                            if (GetLogicalProcessorInformation(Ptr, ref ReturnLength))
                            {
                                int size = Marshal.SizeOf(typeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
                                int len = (int)ReturnLength / size;
                                _logicalProcessorInformation = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[len];
                                IntPtr Item = Ptr;
    
                                for (int i = 0; i < len; i++)
                                {
                                    _logicalProcessorInformation[i] = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)Marshal.PtrToStructure(Item, typeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
                                    Item += size;
                                }
    
                                return _logicalProcessorInformation;
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(Ptr);
                        }
                    }
                    return null;
                }
            }
        }
    

    Handy helper function:

    public static void GetPerCoreCacheSizes(out Int64  L1, out Int64 L2, out Int64 L3)
    {
        L1 = 0;
        L2 = 0;
        L3 = 0;
    
        var info = Processor.LogicalProcessorInformation;
        foreach (var entry in info)
        {
            if (entry.Relationship != Processor.LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache)
                continue;
            Int64 mask = (Int64)entry.ProcessorMask;
            if ((mask & (Int64)1) == 0)
                continue;
            var cache = entry.ProcessorInformation.Cache;
            switch (cache.Level)
            {
                case 1: L1 = L1 + cache.Size; break;
                case 2: L2 = L2 + cache.Size; break;
                case 3: L3 = L3 + cache.Size; break;
                default:
                    break;
            }
        }
    

    And call it:

    static void Main(string[] args)
    {
        long l1, l2, l3;
    
        GetPerCoreCacheSizes(out l1, out l2, out l3);
    
        String s = String.Format("Single-core memory cache: L1={0} KB, L2={1} KB, L3={2} KB", l1 / 1024, l2 / 1024, l3 / 1024);
        Console.WriteLine(s);
        Console.ReadLine();
    }
    

    Output:

    Single-core memory cache: L1=64 KB, L2=256 KB, L3=6144 KB
    
    0 讨论(0)
  • 2021-01-13 11:19

    You can use WMI to retrieve cache information.

    You will first need to add a reference to System.Management.dll to your project, then you can use the following code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management;
    
    namespace Scratch
    {
        public enum CacheLevel : ushort 
        {
            Level1 = 3,
            Level2 = 4,
            Level3 = 5,
        }
    
        public static class CPUInfo
        {
            public static List<uint> GetCacheSizes(CacheLevel level)
            {
                ManagementClass mc = new ManagementClass("Win32_CacheMemory");
                ManagementObjectCollection moc = mc.GetInstances();
                List<uint> cacheSizes = new List<uint>(moc.Count);
    
                cacheSizes.AddRange(moc
                  .Cast<ManagementObject>()
                  .Where(p => (ushort)(p.Properties["Level"].Value) == (ushort)level)
                  .Select(p => (uint)(p.Properties["MaxCacheSize"].Value)));
    
                return cacheSizes;
            }
        }
    }
    

    Full details of the Win32_CacheMemory WMI class is available at:

    http://msdn.microsoft.com/en-us/library/aa394080(v=vs.85).aspx

    0 讨论(0)
提交回复
热议问题