cpuinfo

PURPOSE ^

CPUINFO read CPU configuration

SYNOPSIS ^

function info = cpuinfo()

DESCRIPTION ^

CPUINFO  read CPU configuration

   info = CPUINFO() returns a structure containing various bits of
   information about the CPU and operating system as provided by /proc/cpu
   (Unix), sysctl (Mac) or WMIC (Windows). This information includes:
     * CPU name
     * CPU clock speed
     * CPU Cache size (L2)
     * Number of physical CPU cores
     * Operating system name & version

   See also: COMPUTER, ISUNIX, ISMAC

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function info = cpuinfo()
0002 %CPUINFO  read CPU configuration
0003 %
0004 %   info = CPUINFO() returns a structure containing various bits of
0005 %   information about the CPU and operating system as provided by /proc/cpu
0006 %   (Unix), sysctl (Mac) or WMIC (Windows). This information includes:
0007 %     * CPU name
0008 %     * CPU clock speed
0009 %     * CPU Cache size (L2)
0010 %     * Number of physical CPU cores
0011 %     * Operating system name & version
0012 %
0013 %   See also: COMPUTER, ISUNIX, ISMAC
0014 
0015 %   Author: Ben Tordoff
0016 %   Copyright 2011 The MathWorks, Inc.
0017 
0018 if isunix
0019     if ismac
0020         info = cpuInfoMac();
0021     else
0022         info = cpuInfoUnix();
0023     end
0024 else
0025     info = cpuInfoWindows();
0026 end
0027 
0028 
0029 %-------------------------------------------------------------------------%
0030 function info = cpuInfoWindows()
0031 sysInfo = callWMIC( 'cpu' );
0032 osInfo = callWMIC( 'os' );
0033 
0034 info = struct( ...
0035     'Name', sysInfo.Name, ...
0036     'Clock', [sysInfo.MaxClockSpeed,' MHz'], ...
0037     'Cache', [sysInfo.L2CacheSize,' KB'], ...
0038     'NumProcessors', str2double( sysInfo.NumberOfCores ), ...
0039     'OSType', 'Windows', ...
0040     'OSVersion', osInfo.Caption );
0041 
0042 %-------------------------------------------------------------------------%
0043 function info = callWMIC( alias )
0044 % Call the MS-DOS WMIC (Windows Management) command
0045 olddir = pwd();
0046 cd( tempdir );
0047 sysinfo = evalc( sprintf( '!wmic %s get /value', alias ) );
0048 cd( olddir );
0049 fields = textscan( sysinfo, '%s', 'Delimiter', '\n' ); fields = fields{1};
0050 fields( cellfun( 'isempty', fields ) ) = [];
0051 % Each line has "field=value", so split them
0052 values = cell( size( fields ) );
0053 for ff=1:numel( fields )
0054     idx = find( fields{ff}=='=', 1, 'first' );
0055     if ~isempty( idx ) && idx>1
0056         values{ff} = strtrim( fields{ff}(idx+1:end) );
0057         fields{ff} = strtrim( fields{ff}(1:idx-1) );
0058     end
0059 end
0060 
0061 % Remove any duplicates (only occurs for dual-socket PC's and we will
0062 % assume that all sockets have the same processors in them).
0063 numResults = sum( strcmpi( fields, fields{1} ) );
0064 if numResults>1
0065     % If we are counting cores, sum them.
0066     numCoresEntries = find( strcmpi( fields, 'NumberOfCores' ) );
0067     if ~isempty( numCoresEntries )
0068         cores = cellfun( @str2double, values(numCoresEntries) );
0069         values(numCoresEntries) = {num2str( sum( cores ) )};
0070     end
0071     % Now remove the duplicate results
0072     [fields,idx] = unique(fields,'first');
0073     values = values(idx);
0074 end
0075 
0076 % Convert to a structure
0077 info = cell2struct( values, fields );
0078 
0079 %-------------------------------------------------------------------------%
0080 function info = cpuInfoMac()
0081 machdep = callSysCtl( 'machdep.cpu' );
0082 hw = callSysCtl( 'hw' );
0083 info = struct( ...
0084     'Name', machdep.brand_string, ...
0085     'Clock', [num2str(str2double(hw.cpufrequency_max)/1e6),' MHz'], ...
0086     'Cache', [machdep.cache.size,' KB'], ...
0087     'NumProcessors', str2double( machdep.core_count ), ...
0088     'OSType', 'Mac OS/X', ...
0089     'OSVersion', getOSXVersion() );
0090 
0091 %-------------------------------------------------------------------------%
0092 function info = callSysCtl( namespace )
0093 infostr = evalc( sprintf( '!sysctl -a %s', namespace ) );
0094 % Remove the prefix
0095 infostr = strrep( infostr, [namespace,'.'], '' );
0096 % Now break into a structure
0097 infostr = textscan( infostr, '%s', 'delimiter', '\n' );
0098 infostr = infostr{1};
0099 info = struct();
0100 for ii=1:numel( infostr )
0101     colonIdx = find( infostr{ii}==':', 1, 'first' );
0102     if isempty( colonIdx ) || colonIdx==1 || colonIdx==length(infostr{ii})
0103         continue
0104     end
0105     prefix = infostr{ii}(1:colonIdx-1);
0106     value = strtrim(infostr{ii}(colonIdx+1:end));
0107     while ismember( '.', prefix )
0108         dotIndex = find( prefix=='.', 1, 'last' );
0109         suffix = prefix(dotIndex+1:end);
0110         prefix = prefix(1:dotIndex-1);
0111         value = struct( suffix, value );
0112     end
0113     info.(prefix) = value;
0114     
0115 end
0116 
0117 %-------------------------------------------------------------------------%
0118 function vernum = getOSXVersion()
0119 % Extract the OS version number from the system software version output.
0120 ver = evalc('system(''sw_vers'')');
0121 vernum = regexp(ver, 'ProductVersion:\s([1234567890.]*)', 'tokens', 'once');
0122 vernum = strtrim(vernum{1});
0123 
0124 %-------------------------------------------------------------------------%
0125 function info = cpuInfoUnix()
0126 txt = readCPUInfo();
0127 cpuinfo = parseCPUInfoText( txt );
0128 
0129 txt = readOSInfo();
0130 osinfo = parseOSInfoText( txt );
0131 
0132 % Merge the structures
0133 info = cell2struct( [struct2cell( cpuinfo );struct2cell( osinfo )], ...
0134     [fieldnames( cpuinfo );fieldnames( osinfo )] );
0135 
0136 %-------------------------------------------------------------------------%
0137 function info = parseCPUInfoText( txt )
0138 % Now parse the fields
0139 lookup = {
0140     'model name', 'Name'
0141     'cpu Mhz', 'Clock'
0142     'cpu cores', 'NumProcessors'
0143     'cache size', 'Cache'
0144     };
0145 info = struct( ...
0146     'Name', {''}, ...
0147     'Clock', {''}, ...
0148     'Cache', {''} );
0149 for ii=1:numel( txt )
0150     if isempty( txt{ii} )
0151         continue;
0152     end
0153     % Look for the colon that separates the property name from the value
0154     colon = find( txt{ii}==':', 1, 'first' );
0155     if isempty( colon ) || colon==1 || colon==length( txt{ii} )
0156         continue;
0157     end
0158     fieldName = strtrim( txt{ii}(1:colon-1) );
0159     fieldValue = strtrim( txt{ii}(colon+1:end) );
0160     if isempty( fieldName ) || isempty( fieldValue )
0161         continue;
0162     end
0163     
0164     % Is it one of the fields we're interested in?
0165     idx = find( strcmpi( lookup(:,1), fieldName ) );
0166     if ~isempty( idx )
0167         newName = lookup{idx,2};
0168         info.(newName) = fieldValue;
0169     end
0170 end
0171 
0172 % Convert clock speed
0173 info.Clock = [info.Clock, ' MHz'];
0174 
0175 % Convert num cores
0176 info.NumProcessors = str2double( info.NumProcessors );
0177 
0178 %-------------------------------------------------------------------------%
0179 function info = parseOSInfoText( txt )
0180 info = struct( ...
0181     'OSType', 'Linux', ...
0182     'OSVersion', '' );
0183 % find the string "linux version" then look for the bit in brackets
0184 [~,b] = regexp( txt, '[^\(]*\(([^\)]*)\).*', 'match', 'tokens', 'once' );
0185 info.OSVersion = b{1}{1};
0186 
0187 %-------------------------------------------------------------------------%
0188 function txt = readCPUInfo()
0189 
0190 fid = fopen( '/proc/cpuinfo', 'rt' );
0191 if fid<0
0192     error( 'cpuinfo:BadPROCCPUInfo', 'Could not open /proc/cpuinfo for reading' );
0193 end
0194 onCleanup( @() fclose( fid ) );
0195 
0196 txt = textscan( fid, '%s', 'Delimiter', '\n' );
0197 txt = txt{1};
0198 
0199 %-------------------------------------------------------------------------%
0200 function txt = readOSInfo()
0201 
0202 fid = fopen( '/proc/version', 'rt' );
0203 if fid<0
0204     error( 'cpuinfo:BadProcVersion', 'Could not open /proc/version for reading' );
0205 end
0206 onCleanup( @() fclose( fid ) );
0207 
0208 txt = textscan( fid, '%s', 'Delimiter', '\n' );
0209 txt = txt{1};

Community support and wiki are available on Redmine. Last update: 18-Apr-2019.