-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to get Common System Hardware information across platforms #22948
Comments
|
This is probably a larger discussion and API design we should have about how to get common system information in general across platforms. |
|
Do we want "RuntimeInformation" to encompass this sort of thing? Although there's a real risk of it becoming a "grab bag of stuff" (and it sort of already is...), I'm not sure there's a better place for it. |
|
That was the first thing I thought of. Yes, it may become a grab bag of stuff but hopefully its common information people want / need to know about the hardware, OS, etc. Kinda wish it wasn't under InteropServices but that ship has sailed :( |
|
@mellinoe , do you want to carry this forward and make an API proposal with a basic set of capabilities? |
|
There is some stuff already on Environment of course (and proposals for more -- |
|
Unless we've pivoted in this regard, then we don't want to be adding new stuff into legacy types like |
Sure, I can come up with something. I'll try to come up with some reasonable basic set and see how different OS's expose that info. |
|
It would be very helpful to add new class to System.Diagnostics used solely for the purpose of gathering all important information on the physical system even if this information would be available in other parts of framework. The reason is that besides of running on different operating systems .NET Core may run on different hardware (including IoT and mobile devices). public class System.Diagnostic.Hardware/Machine
// with some of the properties
public static long PhysicalMemory; // (in bytes)
public static int ProcessorSockets;
public static int ProcessorCount;
public static int ProcessorCoreCount; // alternatively ThreadsPerCore (for SMT processors)
public static int USB2Ports;
public static int USB3Ports;
public static int GraphicsAccelerators;
public static int GraphicsMemory;
public static int DisplayCount ; // additional benefit - ability to detect headless hardware
public static int DisplayResolution (ppi)
public static int NetworkInterfaceCount;
public static long NetworkInterfaceSpeed;
public static int Gyroscope;
public static int GyroscopeAxisCount;
public static bool Gps;
public static bool Galileo;
public static bool Compass;
public static int Accelerometer;
public static int AccelerometerAxisCount;
public static int SpeakersCount;
public static int MicrophoneCount;
public static int CameraCount;
public static int CameraResolution; // pixels
public static int HardDriveCount;
public static int HardDriveCapacity;
public static int HardDriveType;The code above is an oversimplified sketch since it would be necessary to provide details for every 'complex' hardware with breakdown of features for every individual device i.e. display, network interface, graphics accelerator, hdd etc. In addition it would be possible to list here selectively only the device types which are currently supported by .NET Framework/Core or list all and throw PNSE for not supported devices i.e. Serial ports but not Jtag port (or PNSE exception for Jtag). This would provide additional level of information on framework for user communicating hardware support matrix of framework. |
|
Another use case here is getting the identifier of various pieces of the hardware to know if you are on the same machine or a different one or if the hardware in the system has changed. Things like Processor Id, BIOS information, and Motherboard information. |
|
There are some new capabilities in Linux kernel which could be useful for collecting hardware and performance data: Windows Management Instrumentation Now A Formal Bus With Linux 4.13. Kernel changes allow for fast feature uptake and can be safely used for forward looking feature implementation. I do not know very much about details of Linux WMI implementation so it would helpful to ask Linux experts for their opinion. |
|
One thing that needs to be reflected in the API is that on some systems, or some configurations of systems, certain pieces of information will not be available, at all. If information is not available or permitted to be accessed by the system, that result should be expressible through the API itself, not as an exception. We can choose a "least common denominator" set of things that we KNOW will be available everywhere, but that isn't useful, especially not for a query API like this. The NetworkInformation types, which I ported a while back to Linux and macOS, are a very good example of what NOT to do in this kind of API. They throw PlatformNotSupportedException's all over the place because many pieces of information are either inaccessible, represented differently, or just plain don't make sense for non-Windows platforms. These API's were never designed to be used outside of Windows, so it's not a surprise that they don't work well on Linux or Mac. |
Agree that PSNE exception is not very useful type of information from hardware query. But in principle what has to be presented to user this is the following matrix of capabilities:
This could be encapsulated in simple enum and property plus capabilities query i.e.: public enum HardwareInfo
{
Unknown = 0,
NoInfo,
NoInfoOnPlatform,
NoAccess,
Partial,
Full
}
public abstract class DeviceInfo
{
public HardwareInfo HardwareInfo { get; protected set; }
// Capabilities query similar to RuntimeInformation
public abstract HardwareInfo IsSupported(string queryCapability);
}
[Flags]
public enum ProcessorConfiguration
{
Unknown = 0,
SymmetricMultiProcessing = 1,
BigLittle = 2,
// APU means that processor contains general purpose CPU core(s) and some accelerators
ApplicationProccessingUnit = 4,
GraphicsAccelerator = 8,
FpgaAccelerator = 16,
AiAccelerator = 32
}
public class ProcessorInfo : DeviceInfo
{
public int SocketsCount { get; protected set; }
public int ProcessorCount { get; protected set; }
public enum ProcessorConfiguration { get; protected set; }
// Override abstract IsSupported
public override HardwareInfo IsSupported(string queryCapability)
{
switch(queryCapability)
{
case namof(SocketsCount):
return QuerySocketsCountCapabilities();
case nameof(ProcessorCount):
return QueryProcessorCountCapabilities();
case nameof(ProcessorConfiguration):
return QueryProcessorConfigurationCapabilities();
default:
throw new ArgumentException(nameof(queryCapability));
}
}
}
public class SmpProcessorInfo : ProcessorInfo
{
public int CoreCount {get; protected set; }
public int ThreadsPerCore { get; protected set; }
public InstructionSet InstructionSet { get; protected set; }
// Override abstract IsSupported
public override HardwareInfo IsSupported(string queryCapability)
{
// implementation
}
}
// First look at this problem
public class BigLittleProcessorInfo : ProcessorInfo
{
public CoreType[] CoreTypes { get; protected set; }
public IReadOnlyDictionary<CoreType, int>CoreCount { get; protected set; }
public IReadOnlyDictionary<CoreType, int>ThreadsPerCore { get; protected set; }
public IReadOnlyDictionary<CoreType, InstructionSet> InstructionSet { get; protected set; }
// Override abstract IsSupported
public override HardwareInfo IsSupported(string queryCapability)
{
// implementation
}
}
// Most important values i.e. for SIMD intrinsics
[Flags]
public enum CpuidX86 : ulong
{
Unknwown = 0,
// No values set at this stage
Sse,
Sse2,
Sse3,
Ssse3,
Sse41,
Sse42,
Avx,
Avx2,
Avx512, // This one has to be more complex
Aes,
Fma,
Tsx,
.....
}
public struct CpuidValue
{
public uint EAX;
public uint EBX;
public uint ECX;
public uint EDX;
}
public class X86ProcessorInfo : SmpProcessorInfo
{
public CpuidX86 Cpuid { get; protected set; }
public int FirstLevelCache { get; protected set; }
public int SecondLevelCache { get; protected set; }
public bool IsSecondLevelCacheShared { get; protected set; }
public int ThirdLevelCache { get; protected set; }
public bool IsThirdLevelCacheShared { get; protected set; }
// other items ......
// Override abstract IsSupported
public override HardwareInfo IsSupported(string queryCapability)
{
// implementation
}
public static CpuidValue GetCpuid(uint eaxQueryValue) { }
}
public class PowerProcessorInfo : SmpProcessorInfo
{
....
}
public class ArmSmpProcessorInfo : SmpProcessorInfo
{
....
}
public class ArmBlProcessorInfo : BigLittleProcessorInfo
{
....
}
public class Hardware
{
public static HardwareInfo IsSupported(string queryCapability)
{
switch(queryCapability)
{
case namof(ProcessorInfo):
return QueryProcessorInfoCapabilities();
// ......
}
// could be null - in this case check what is the reason
public static ProcessorInfo ProcessorInfo { get; private set; }
// all other devices
}
// usage
var processor = Hardware.ProcessorInfo;
if (processor is ArmSmpProcessorInfo armProc)
{
// use armProc in code
}
else if (processor is X86ProcessorInfo x86Proc)
{
// use x86Proc
}
else
{
var support = Hardware.IsSupported(nameof(Hardware.ProcessorInfo));
// use support info
}This is loose outline how it can be done for processor. I think that this kind of pattern which tries to get only hardware features and not OS hardware abstractions would be most meaningful one and would escape problem of being not present in given OS. If info is not available one can query support. Above example could be very useful for determining SIMD support on given platform - see issue dotnet/corefx#22843 |
|
@mellinoe , should we start a prototype or two in corefxlab and start filling in some of these ideas? |
|
@mellinoe @Petermarcu I would volunteer to do some work in such project if team would be interested |
|
@ericstj as well. Let's see if we can get a proposal together and get a project rolling. |
|
I've been thinking about this and wanted to share a few principles that we should remember from past API.
Things like CPU cores|clock|cache and memory all make sense for potentially making CPU vs memory tradeoffs. Some set of hardware identifiers that are exceptionally stable may make sense for machine identification. I'm not sure about the others (eg: camera, display, gps, etc): how would someone make use of those without some sort of abstraction for actually interacting with those devices? If folks can enumerate some more scenarios that would help. |
|
Are there relevant de facto standards for this info - such that libraries exist on both Unix and Windows? Perhaps then our API could be relatively thin? |
|
For device enumeration Windows has Setup API and WMI. Setup API was never something we had inbox in .NET (though many folks have written wrappers) but we did have System.Management for WMI. I believe the equivalent is on linux is libudev. I haven't looked at Linux's WMI implementation @4creators mentioned above but that'd be something to examine as part of the System.Management issue. I still question how useful device enumeration is without having some common way of interacting with the devices. For instance: what good is it to know the machine has a GPU unless I can give it work to do? What good is it to know that the machine has a GPS unless I can read its coordinates? I think we need to fully describe the scenarios we're trying to enable to make sure we're scoping this correctly. "Wrap device enumeration" while interesting is probably not something we want to lump together with "expose the amount of memory and CPUs available on the machine". I think we should scope this issue down to some key scenarios then design the API that fits those. |
|
I don't really have more time at the moment for this, maybe in the coming weeks. |
|
ok, flagging it as up-for-grabs then so that if anybody else is interested on this they can throw a proposal. |
|
@joperezr |
|
I need to grasb Linux harware info such as following some java code is as following SystemInfo si = new SystemInfo(); 1 Model via computerSystem.getModel()) Can anybody help me in it? Even if somebody point me to third party nuget package then it will also be helpful |
|
@baruchiro I'm not super familiar with RuntimeInformation but it seems to be that we mostly just get all the current information from Pinvoking into native functions like the following: I'm not sure if all the requested information will be easy to get on all of our supported Unix distros, but I think that is the point of this issue. The idea is to find if there is extra runtime information that we can consistently get across all of our supported OSes without introducing new dependencies (like the need to install a new native dependency on the system). Once that is found, we will need to find an Api proposal that will have to pass through a review to see if this is something we want to add to the framework, and if it is, then we will add it. Here is a list of the next steps to do here:
|
Closes #851. Using the same definition of "complete" as the log message. If it did fewer than 100 items, then nothing is sent to prevent spamming for every small change. Open to suggestions for another arbitrary condition instead. I'd include the system memory, but that'd require a bunch of code to make it work cross platform (or waiting for dotnet/corefx#22660).
|
Hi! |
|
I think this should be implemented as soon as possible. .NET Core is about 3.0, this issue is not suitable for |
|
Returning non-virtualized system-wide data does not make sense in containers. |
|
Yeah, but I'm not using containers. 😉 I'm fully aware that inside containers you have a very limited view on the host system. |
|
@jkotas: that is really on a case-by-case basis, no? Specifically, CPU topology and memory would have to be container aware. |
|
Some of my projects are planning to be hosted in Linux but I can't get the hardware info. Is there any update on this? or anybody will be working on this? |
At the current time you have to be specific about what hardware information currently you requires. There are limited support and some workaround as listed above which can be used scenario by scenario |
|
I think you will find partial overlap between what you want and what WILL be provided in: |
|
@KamranShahid the specific hardwares are cpu, disk, network, board, memory, the information include the name, unique id, manufacture or some other infomations wihch like the WMI can provided before. some of the product require a license based on the hardware and now we need to rewrite this in C++ insead of .net core. |
|
find this MatthewKing/DeviceId |
It s up-to you. Mine problem was solved as per above hack that time |
|
I find the following names ambiguous, is this indicating the cache exists? it's size and if so what metric. (Potentially only comments but a better name would also help) public int FirstLevelCacheSize { get; protected set; }
public int SecondLevelCache { get; protected set; }
public int ThirdLevelCache { get; protected set; }What I am mainly looking for out of this is an easy way to determine when tis best to ATTEMPT to go parallel, see #37602 for further info. Thank you for your time! |
|
It 's a long time for looking forwart this function. |
@KamranShahid My attempt at cross platform hardware info: https://github.com/Jinjinov/Hardware.Info |
|
As noted above the next step here is for someone passionate to reach consensus among those interested on a formal proposal following the template. My suggestion is to do this in increments, starting with a proposal for the most key part - maybe that's cache size. It may be clearer to create that as a new issue, following that template. |
Thank you |
@heartlocker commented on Mon Jul 24 2017
As the .NET Core project could run on Windows, Linux and Mac OS. Is it possible for me to get the PhysicalMemory size of the running machine on these three OS. Just like in .NET framework, by using
Microsoft.VisualBasic.Devices.ComputerInfoto get the Physical Memory information of the windows machine@Petermarcu commented on Wed Jul 26 2017
@AlexGhiondea , should this issue be moved to CoreFX to make an API proposal?
@AlexGhiondea commented on Wed Jul 26 2017
@Petermarcu yes -- I will move it.
The text was updated successfully, but these errors were encountered: