From 82cc7fb84f02eef5508cd1b27b8284e367b06884 Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Sat, 15 Dec 2018 12:27:52 +0100 Subject: [PATCH] cpu() added physical cores, processors, socket type --- CHANGELOG.md | 1 + README.md | 5 +- lib/cpu.js | 180 ++++++++++++++++++++++++++++++++++++++++++++++----- lib/util.js | 13 ++++ package.json | 6 ++ 5 files changed, 187 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 891291b..2f7dcb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ Other changes | Version | Date | Comment | | -------------- | -------------- | -------- | +| 3.52.0 | 2018-12-15 | `cpu()` added physical cores, processors, socket type | | 3.51.4 | 2018-12-05 | `versions()` bugfix, optimization postgres | | 3.51.3 | 2018-11-27 | `mem()` refactoring parsing linux, code cleanup | | 3.51.2 | 2018-11-26 | `mem()` bugfix parsing `free` output linux | diff --git a/README.md b/README.md index d571feb..f8bc6ab 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ async function cpu() { (last 7 major and minor version releases) +- Version 3.52.0: `cpu()` added physical cores, processors, socket type - Version 3.51.0: `processLoad()` added for windows - Version 3.50.0: `services()` added possibility to specify ALL services "*" for linux/win - Version 3.49.0: `uuid()` added - os specific uuid (per installation) @@ -71,7 +72,6 @@ async function cpu() { - Version 3.47.0: `version()` added docker, postfix - Version 3.46.0: `version()` added system openssl version (besides the one inside node.js) - Version 3.45.0: `diskLayout()` added S.M.A.R.T. status -- Version 3.44.0: `battery()` added type, model, manufacturer, serial, timeremaining - ... You can find all changes here: [detailed changelog][changelog-url] @@ -139,6 +139,9 @@ I also created a nice little command line tool called [mmon][mmon-github-url] ( | | speedmin | X | | X | X | | in GHz e.g. '0.80' | | | speedmax | X | X | X | X | | in GHz e.g. '3.90' | | | cores | X | X | X | X | | # cores | +| | physicalCores | X | X | X | X | | # physical cores | +| | processors | X | X | X | X | | # processors | +| | socket | X | X | | X | | socket type e.g. "LGA1356" | | | vendor | X | X | X | X | | vendor ID | | | family | X | X | X | X | | processor family | | | Model | X | X | X | X | | processor model | diff --git a/lib/cpu.js b/lib/cpu.js index 3898e32..acc4711 100644 --- a/lib/cpu.js +++ b/lib/cpu.js @@ -14,6 +14,7 @@ const os = require('os'); const exec = require('child_process').exec; +const execSync = require('child_process').execSync; const fs = require('fs'); const util = require('./util'); @@ -100,6 +101,15 @@ const AMDBaseFrequencies = { 'Pro 1300': '3.5', '1200': '3.1', 'Pro 1200': '3.1', + '2200U': '2.5', + '2300U': '2.0', + 'Pro 2300U': '2.0', + '2500U': '2.0', + 'Pro 2500U': '2.2', + '2700U': '2.0', + 'Pro 2700U': '2.2', + '2600H': '3.2', + '2800H': '3.3', '7601': '2.2', '7551': '2.0', '7501': '2.0', @@ -112,6 +122,69 @@ const AMDBaseFrequencies = { '7551P': '2.0', '7401P': '2.0', '7351P': '2.4' +} + +const socketTypes = { + 1: 'Other', + 2: 'Unknown', + 3: 'Daughter Board', + 4: 'ZIF Socket', + 5: 'Replacement/Piggy Back', + 6: 'None', + 7: 'LIF Socket', + 8: 'Slot 1', + 9: 'Slot 2', + 10: '370 Pin Socket', + 11: 'Slot A', + 12: 'Slot M', + 13: '423', + 14: 'A (Socket 462)', + 15: '478', + 16: '754', + 17: '940', + 18: '939', + 19: 'mPGA604', + 20: 'LGA771', + 21: 'LGA775', + 22: 'S1', + 23: 'AM2', + 24: 'F (1207)', + 25: 'LGA1366', + 26: 'G34', + 27: 'AM3', + 28: 'C32', + 29: 'LGA1156', + 30: 'LGA1567', + 31: 'PGA988A', + 32: 'BGA1288', + 33: 'rPGA988B', + 34: 'BGA1023', + 35: 'BGA1224', + 36: 'LGA1155', + 37: 'LGA1356', + 38: 'LGA2011', + 39: 'FS1', + 40: 'FS2', + 41: 'FM1', + 42: 'FM2', + 43: 'LGA2011-3', + 44: 'LGA1356-3', + 45: 'LGA1150', + 46: 'BGA1168', + 47: 'BGA1234', + 48: 'BGA1364', + 49: 'AM4', + 50: 'LGA1151', + 51: 'BGA1356', + 52: 'BGA1440', + 53: 'BGA1515', + 54: 'LGA3647-1', + 55: 'SP3', + 56: 'SP3r2', + 57: 'LGA2066', + 58: 'BGA1392', + 59: 'BGA1510', + 60: 'BGA1528' }; function cpuBrandManufacturer(res) { @@ -167,26 +240,38 @@ function getCpu() { speedmin: '', speedmax: '', cores: util.cores(), + physicalCores: util.cores(), + processors: 1, + socket: '', cache: {} }; if (_darwin) { - exec('sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min', function (error, stdout) { - if (!error) { - let lines = stdout.toString().split('\n'); - const modelline = util.getValue(lines, 'machdep.cpu.brand_string'); - result.brand = modelline.split('@')[0].trim(); - result.speed = modelline.split('@')[1].trim(); - result.speed = parseFloat(result.speed.replace(/GHz+/g, '')).toFixed(2); - _cpu_speed = result.speed; - result = cpuBrandManufacturer(result); - result.speedmin = (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0).toFixed(2); - result.speedmax = (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0).toFixed(2); - result.vendor = util.getValue(lines, 'machdep.cpu.vendor'); - result.family = util.getValue(lines, 'machdep.cpu.family'); - result.model = util.getValue(lines, 'machdep.cpu.model'); - result.stepping = util.getValue(lines, 'machdep.cpu.stepping'); - + exec('sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min hw.packages hw.physicalcpu_max hw.ncpu', function (error, stdout) { + // if (!error) { + let lines = stdout.toString().split('\n'); + const modelline = util.getValue(lines, 'machdep.cpu.brand_string'); + result.brand = modelline.split('@')[0].trim(); + result.speed = modelline.split('@')[1].trim(); + result.speed = parseFloat(result.speed.replace(/GHz+/g, '')).toFixed(2); + _cpu_speed = result.speed; + result = cpuBrandManufacturer(result); + result.speedmin = (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0).toFixed(2); + result.speedmax = (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0).toFixed(2); + result.vendor = util.getValue(lines, 'machdep.cpu.vendor'); + result.family = util.getValue(lines, 'machdep.cpu.family'); + result.model = util.getValue(lines, 'machdep.cpu.model'); + result.stepping = util.getValue(lines, 'machdep.cpu.stepping'); + const countProcessors = util.getValue(lines, 'hw.packages'); + const countCores = util.getValue(lines, 'hw.physicalcpu_max'); + const countThreads = util.getValue(lines, 'hw.ncpu'); + if (countProcessors) { + result.processors = parseInt(countProcessors) || 1; } + if (countCores && countThreads) { + result.cores = parseInt(countThreads) || util.cores(); + result.physicalCores = parseInt(countCores) || util.cores(); + } + // } cpuCache().then(res => { result.cache = res; resolve(result); @@ -234,6 +319,42 @@ function getCpu() { if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1); } result.cache.l3 = util.getValue(lines, 'l3 cache'); if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1); } + + // # processurs & # threads/core - method 1 + let threadsPerCoreInt = 0; + try { + lines = []; + lines = execSync('cat /proc/cpuinfo | grep -E "physical id|core id"').toString().split('\n'); + if (lines && lines.length) { + result.processors = util.countUniqueLines(lines, 'physical id') || 1; + result.physicalCores = util.countUniqueLines(lines, 'core id') / result.processors; + if (result.physicalCores) { + threadsPerCoreInt = result.cores / result.physicalCores; + } + } + } catch (e) { + util.noop(); + } + // # threads/core - method 2 + if (threadsPerCoreInt === 0) { + const threadsPerCore = util.getValue(lines, 'thread(s) per core'); + if (threadsPerCore) { + threadsPerCoreInt = parseInt(threadsPerCore, 10); + if (!isNaN(threadsPerCoreInt)) { + result.physicalCores = result.cores / threadsPerCoreInt; + } + } + } + // socket type + try { + lines = []; + lines = execSync('dmidecode –t 4 | grep "Upgrade: Socket"').toString().split('\n'); + if (lines && lines.length) { + result.socket = util.getValue(lines, 'Upgrade').replace('Socket', '').trim(); + } + } catch (e) { + util.noop(); + } resolve(result); }); } @@ -294,6 +415,15 @@ function getCpu() { } } } + // socket type + result.socket = util.getValue(lines, 'Upgrade').replace('Socket', '').trim(); + // # threads / # cores + const threadCount = util.getValue(lines, 'thread count').trim(); + const coreCount = util.getValue(lines, 'core count').trim(); + if (coreCount && threadCount) { + result.cores = threadCount; + result.physicalCores = coreCount; + } resolve(result); }); } @@ -302,7 +432,7 @@ function getCpu() { } if (_windows) { try { - exec(util.getWmic() + ' cpu get name, description, revision, l2cachesize, l3cachesize, manufacturer, currentclockspeed, maxclockspeed /value', util.execOptsWin, function (error, stdout) { + exec(util.getWmic() + ' cpu get /value', util.execOptsWin, function (error, stdout) { if (!error) { let lines = stdout.split('\r\n'); let name = util.getValue(lines, 'name', '=') || ''; @@ -345,6 +475,22 @@ function getCpu() { result.stepping = description[i + 1]; } } + // socket type + const socketId = util.getValue(lines, 'UpgradeMethod', '='); + if (socketTypes[socketId]) { + result.socket = socketTypes[socketId]; + } + // # threads / # cores + const countProcessors = util.countUniqueLines(lines, 'Caption'); + const countThreads = util.getValue(lines, 'NumberOfLogicalProcessors', '='); + const countCores = util.getValue(lines, 'NumberOfCores', '='); + if (countProcessors) { + result.processors = parseInt(countProcessors) || 1; + } + if (countCores && countThreads) { + result.cores = parseInt(countThreads) || util.cores(); + result.physicalCores = parseInt(countCores) || util.cores(); + } } exec(util.getWmic() + ' path Win32_CacheMemory get CacheType,InstalledSize,Purpose', function (error, stdout) { if (!error) { diff --git a/lib/util.js b/lib/util.js index 13309b7..2bd27ef 100644 --- a/lib/util.js +++ b/lib/util.js @@ -291,6 +291,18 @@ function nanoSeconds() { return +time[0] * 1e9 + +time[1]; } +function countUniqueLines(lines, startingWith) { + startingWith = startingWith || ''; + const uniqueLines = []; + lines.forEach(line => { + if (line.indexOf(startingWith) === 0) { + if (uniqueLines.indexOf(line) === -1) { + uniqueLines.push(line); + } + } + }); + return uniqueLines.length; +} function noop() { } exports.execOptsWin = execOptsWin; @@ -308,4 +320,5 @@ exports.findObjectByKey = findObjectByKey; exports.getWmic = getWmic; exports.powerShell = powerShell; exports.nanoSeconds = nanoSeconds; +exports.countUniqueLines = countUniqueLines; exports.noop = noop; diff --git a/package.json b/package.json index 987cce1..a7afdda 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,12 @@ "freebsd", "cpu", "cpuload", + "physical cores", + "logical cores", + "processor", + "cores", + "threads", + "socket type", "memory", "file system", "fsstats",