IT Support & Help Desk Fundamentals Module 3 – Hardware and peripherals
Inside a computer: CPU, RAM, board and GPU
Read a machine for the facts behind an upgrade ticket: CPU family and cores, RAM type and channels, board sockets, PCIe and VRAM, on Windows, macOS and Linux.
What you will learn
- Decide from a ticket and a specification sheet whether a laptop can take a memory upgrade
- Identify a machine's CPU family and say whether an app built for the other family can run
- Distinguish cores, logical processors, memory channels and PCIe lanes on a specification sheet
- Explain what integrated graphics and dedicated VRAM mean for an application's video memory requirement
- Read the CPU, cores, memory and graphics from the command line on Windows, macOS and Linux
Before you start
What you’ll learn · Before you start
What you will learn
- Decide from a ticket and a specification sheet whether a laptop can take a memory upgrade
- Identify a machine's CPU family and say whether an app built for the other family can run
- Distinguish cores, logical processors, memory channels and PCIe lanes on a specification sheet
- Explain what integrated graphics and dedicated VRAM mean for an application's video memory requirement
- Read the CPU, cores, memory and graphics from the command line on Windows, macOS and Linux
Before you start
On this page
A user asks whether their laptop can take 32 GB, and whether the design app will run, because it “needs 4 GB of video memory”. Both answers are numbers that the machine and its specification sheet hold. On the Mac this lesson’s examples ran on, they read Apple M5 Pro, 18 cores and 48 GB of memory that sits inside the chip’s package, with no separate video memory at all. A laptop with two SO-DIMM slots that take 32 GB each can reach 64 GB; one with soldered memory cannot take another gigabyte.
You will name the parts behind those numbers (the CPU, the memory, the board’s sockets and the graphics), read the limits that decide an upgrade, and use the commands that report them on Windows, macOS and Linux. The last exercise reads all three systems into one record.
Every hardware ticket comes down to three readings
Take the ticket from the opening: a user has 16 GB and wants 32 GB. Nothing in that sentence says whether it is possible, because the limit lives in the parts, not in the request. “Run this on my Mac” and “the app needs a 4 GB card” are the same kind of request. Each one becomes a reading from the machine, a reading from the maker’s specification of that exact model, and a little arithmetic.
| The ticket says | Read from the machine | Read from the specification | The answer allows |
|---|---|---|---|
| More memory | Memory installed, and its type | Memory form, slots, largest module | An upgrade, a plan, or none |
| Run this app | The CPU family | Which families the app supports | Native, translated, or not at all |
| Needs a 4 GB card | The graphics chip and its memory | Dedicated or shared memory | The requirement is met or not |
A fourth request, “add a second drive”, works the same way and has its own lesson: storage drives and RAID. Step through the memory ticket below. Its numbers belong to “Laptop A”, a specification sheet invented for this lesson so that every figure can be checked:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- The ticket. A user has 16 GB and asks for 32 GB. Do not answer from memory: the answer is in three facts, one from the machine, one from the maker and one from arithmetic.
- The exact model. Read the model name from the machine itself. The maker publishes one specification sheet per model, and two laptops of the same brand and year can differ in whether their memory can be changed.
- What is fitted now. An inventory command shows 16 GB and a memory type of DDR5. The sheet says the 16 GB is one SO-DIMM module in one of two slots, so the memory is not soldered.
- The limits. The sheet lists the largest module the slots accept, 32 GB, and 64 GB in total. 32 GB is inside both limits, and the memory type matches what is fitted.
- What the answer allows. Yes: add a second 16 GB module, or replace the first with two 16 GB modules. A matched pair keeps both memory channels in use, so a pair is better than one 32 GB module.
The last step is the habit to keep: the answer is a plan, not a bare yes. Two 16 GB modules rather than one 32 GB module keep both memory channels busy, which the memory section explains.
Answering from the make of the laptop
Wrong: “That make always takes 64 GB, order it.” Right: read the specification of this exact model. A maker sells socketed and soldered models under one name, and a wrong guess shows only when the memory arrives and has nowhere to go.
Checkpoint
Check: From a ticket to three readings
The CPU family decides which apps run, and cores count three ways
Start with the family, because it decides whether an installer or a driver works at all. x86-64: The processor family of Intel and AMD chips in most Windows PCs, many Linux machines and older Macs. Software built for it does not run on Arm64 chips without translation. is the family of Intel and AMD processors, found in most Windows PCs and many Linux machines. Arm64: The 64-bit Arm processor family of Apple silicon Macs, Windows on Arm laptops, phones and many servers. Software built only for x86-64 needs translation to run on it. is the family of Apple silicon Macs, Windows on Arm laptops, phones and tablets. A program built for one family does not run on the other unless something translates it. This session asked the Mac of the lesson’s examples which chip it has, how many cores and logical processors, how much memory and which family, then repeated the facts from the hardware and graphics reports:
from session import run
# What this Mac says about its own processor, cores and memory. The first four commands answer "which CPU, how many
# cores, how many logical processors, how much memory"; the fifth names the processor family; the last repeats the
# same facts from the hardware report, which also says how the cores are split. The last line asks for the graphics
# chip and any video memory line.
run("""
sysctl -n machdep.cpu.brand_string
sysctl -n hw.physicalcpu
sysctl -n hw.logicalcpu
sysctl -n hw.memsize
uname -m
system_profiler -detailLevel mini SPHardwareDataType | grep -E 'Chip|Total Number of Cores|Memory'
system_profiler -detailLevel mini SPDisplaysDataType | grep -E 'Chipset Model|Type|Bus|Total Number of Cores|VRAM'
""") Output
$ sysctl -n machdep.cpu.brand_string
Apple M5 Pro
$ sysctl -n hw.physicalcpu
18
$ sysctl -n hw.logicalcpu
18
$ sysctl -n hw.memsize
51539607552
$ uname -m
arm64
$ system_profiler -detailLevel mini SPHardwareDataType | grep -E 'Chip|Total Number of Cores|Memory'
Chip: Apple M5 Pro
Total Number of Cores: 18 (6 Super and 12 Performance)
Memory: 48 GB
$ system_profiler -detailLevel mini SPDisplaysDataType | grep -E 'Chipset Model|Type|Bus|Total Number of Cores|VRAM'
Chipset Model: Apple M5 Pro
Type: GPU
Bus: Built-In
Total Number of Cores: 20
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 hardware_session.py
uname -m prints arm64, so this is an Arm64 machine, and machdep.cpu.brand_string names the chip: Apple M5 Pro.
The memory is 51,539,607,552 bytes, which is 48 GiB (divide by 2 to the power 30, as in
bits, bytes and storage units); the report writes it as 48 GB. The
data storage converter does that division for any size.
Translation exists, with limits. Microsoft documents that Windows 11 on Arm supports instruction-set emulation: Software that translates a program built for one processor family so that it runs on another, such as x64 apps on Windows on Arm or Intel apps through Rosetta on a Mac. of both x86 and x64 apps, and that the emulator, Prism, arrived with Windows 11 version 24H2. The same page says emulation “only supports user mode code and doesn’t support drivers”, so a program that installs a kernel driver needs an Arm64 build of the driver itself. On a Mac the translator is Rosetta, and Apple’s support article says it is available on macOS 27 or earlier; from macOS 28 only certain older games keep it. An Intel-only app on an Apple silicon Mac is therefore a plan with an end, not a permanent answer. At the desk, select the app in the Finder, choose Get Info and read the Kind line: Intel, Universal or Apple silicon.
Then the counts. Three numbers share the word “cores” on specification sheets and tickets:
- CPU core: One physical processing unit inside a processor. A chip with 8 cores can run 8 programs at the same moment, or 16 threads when each core runs two. are the physical processing units, the
NumberOfCoresof Windows. AMD’s sheet for the Ryzen 7 7700 lists 8. - logical processor: A hardware thread that the operating system can schedule work on. With hyperthreading or SMT each core shows two, so 8 cores can report 16 logical processors., also called threads, are what the operating system schedules work on. With hyperthreading or
SMT each core shows two, and the same sheet lists 16 threads. Microsoft’s advice is to compare
NumberOfLogicalProcessorswithNumberOfCores; the logical count includes only threads that are enabled. The Mac above has 18 of each, so it runs one thread per core. - Core types are a split of the cores by design. The hardware report calls the Mac’s 18 cores “6 Super and 12 Performance”; the number to quote in a ticket is still 18, with the split as a detail.
Key idea
A CPU is described by three facts: its family, its physical cores and its logical processors. Write all three in the ticket (“Arm64, 18 cores, 18 threads”) rather than a bare “18-core”.
Inside a virtual machine the counts describe the guest. The lscpu manual says that in virtualized environments the information reflects the configuration of the guest operating system, which is typically different from the physical host.
Checkpoint
Check: CPU family, emulation and core counts
Memory is either a module you can change or a chip you cannot
Memory comes in three forms, and the first reading is which one:
- A DIMM: A dual in-line memory module: the full-size stick of memory used in desktop computers and servers. One module goes into one slot on the motherboard. is the full-size stick of desktops and servers.
- A SO-DIMM: A small outline DIMM: the shorter memory module used in many laptops, mini PCs and all-in-one computers. It is not interchangeable with a full-size DIMM. is the shorter module of many laptops and small PCs.
- Soldered memory is chips fixed to the board, with no slot at all. Apple describes the Mac’s unified memory: One pool of memory, in the processor's package, that the CPU and the graphics unit share. Its size is set by the configuration chosen when the Mac is bought. as bringing memory “into a single pool within a custom package”, which is why the Mac in the session has no memory slot.
The same processor can be sold in more than one form. AMD’s sheet for the Ryzen 7 7840HS laptop processor lists DDR5 with SO-DIMM modules and also LPDDR5X, a low-power type that laptop makers usually solder. The processor’s sheet shows what is possible; only the laptop’s own sheet shows what was built.
The type matters as much as the form. Micron states that DDR5 memory and DDR4 motherboards are “physically and electrically incompatible”, so a spare DDR4 module is not a slower option for a DDR5 laptop, it is no option. The speed in the label, such as DDR5-5600, is in megatransfers per second (MT/s). Each transfer moves 8 bytes over one 64-bit memory channel: An independent path between the processor and its memory. Modules fitted in matched pairs across two channels move about twice the data of one module on one channel., so one channel peaks at 5,600 × 8 = 44,800 MB/s. AMD’s Ryzen 7 7700 sheet lists two channels, and a limit of 128 GB for the processor, which the board may lower. It also lists DDR5-5200 with two modules but DDR5-3600 with four: more capacity, lower speed.
The program below applies these readings to three invented specification sheets and to the lesson’s Mac, then prints the peak rates for the speeds named above:
"""Can this laptop take 32 GB? Three sample spec sheets and one recorded Mac, then the peak speed of the memory.
The spec sheets are INVENTED for the lesson (the numbers are typical, the models do not exist). The Mac line is the
lesson's recorded session. Memory sizes are in GB as the module labels count them (binary: 16 GB = 16 GiB).
"""
TARGET = 32
SIZES = [4, 8, 16, 32, 64] # module sizes that exist
# name, soldered GB, module slots in total (modules already fitted are replaced), largest module the maker lists, type
MODELS = [
("Laptop A", 0, 2, 32, "DDR5 SO-DIMM"),
("Laptop B", 16, 0, 0, "LPDDR5X soldered"),
("Laptop C", 8, 1, 16, "DDR4 SO-DIMM"),
("The lesson's Mac", 48, 0, 0, "unified memory in the chip package"),
]
def plan(soldered, slots, biggest):
"""The ways to reach TARGET GB, most modules first. Equal modules keep the channels matched."""
ways = []
for count in range(1, slots + 1):
for size in SIZES:
if size <= biggest and soldered + count * size == TARGET:
ways.append(f"{count} x {size} GB")
return sorted(ways, key=lambda w: -int(w.split()[0]))
print(f"{'model':<17} {'max total':>9} {'holds 32?':<9} how")
for name, soldered, slots, biggest, kind in MODELS:
top = soldered + slots * biggest
ways = plan(soldered, slots, biggest)
if soldered >= TARGET:
how = f"already {soldered} GB, {kind}, fixed at purchase"
elif ways:
how = ways[0] + (" (two matched modules: dual channel)" if ways[0].startswith("2") else "")
elif top >= TARGET:
how = "reachable only with a different mix of modules"
else:
how = f"no: the most it can hold is {top} GB ({kind})"
print(f"{name:<17} {top:>6} GB {'yes' if top >= TARGET else 'no':<9} {how}")
print()
print("Peak transfer rate = transfers per second x 8 bytes x channels (theoretical, in GB/s)")
print(f"{'memory':<30} {'1 channel':>9} {'2 channels':>10}")
for label, mts in [
("DDR4-3200", 3200),
("DDR5-5600", 5600),
("DDR5-5200 (2 modules, AMD)", 5200),
("DDR5-3600 (4 modules, AMD)", 3600),
]:
one = mts * 8 / 1000
print(f"{label:<30} {one:>9.1f} {2 * one:>10.1f}") Output
model max total holds 32? how Laptop A 64 GB yes 2 x 16 GB (two matched modules: dual channel) Laptop B 16 GB no no: the most it can hold is 16 GB (LPDDR5X soldered) Laptop C 24 GB no no: the most it can hold is 24 GB (DDR4 SO-DIMM) The lesson's Mac 48 GB yes already 48 GB, unified memory in the chip package, fixed at purchase Peak transfer rate = transfers per second x 8 bytes x channels (theoretical, in GB/s) memory 1 channel 2 channels DDR4-3200 25.6 51.2 DDR5-5600 44.8 89.6 DDR5-5200 (2 modules, AMD) 41.6 83.2 DDR5-3600 (4 modules, AMD) 28.8 57.6
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 memory_limits.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
Laptop A can reach 32 GB as two matched 16 GB modules. Laptop B tops out at its soldered 16 GB, and Laptop C at 24 GB: 8 GB soldered plus one slot that takes 16 GB. The Mac already holds 48 GB, fixed at purchase. In the second table, two channels of DDR5-5600 peak at 89.6 GB/s, and the AMD speeds show the cost of filling four slots: 83.2 GB/s at DDR5-5200 against 57.6 GB/s at DDR5-3600, about 31 % lower. These are theoretical peaks, useful for comparing options, not for promising a benchmark result.
Add a fourth sheet
Press Edit and add ("Laptop D", 16, 1, 32, "DDR5 SO-DIMM") to MODELS. Before you run it, predict the last two
columns: 16 GB soldered plus one slot of up to 32 GB reaches 48 GB, and 32 GB needs one 16 GB module.
ECC memory: Memory that stores extra check bits with the data, typically 8 for every 64, so the system can correct a single flipped bit. The processor, board and modules must all support it. stores check bits beside the data so that a single flipped bit can be corrected. The Linux kernel’s documentation describes the path as typically 72 bits wide to carry 64 bits of data plus 8 bits of ECC data. It needs the processor, the board and the modules to support it together: AMD’s sheet for the Ryzen 7 7700 reads “Yes (Requires mobo support)”, and the 7840HS laptop sheet reads “No”. Samsung adds that DDR5 chips correct single-bit errors inside the chip itself, which is a separate feature from the ECC memory a workstation board checks across the whole module.
Checkpoint
Check: Memory form, type, channels and ECC
Board size and sockets decide what can be added
The board sets the next limits. Its size and layout are its motherboard form factor: The standard that fixes a board's size, mounting holes and layout, such as ATX, microATX or mini-ITX, so that boards and cases from different makers fit together.. The ATX Specification gives a full-size ATX board as 12 by 9.6 inches (305 by 244 mm) with up to seven expansion slots, and notes that many ATX cases take the smaller microATX boards too. Smaller boards offer fewer slots, so when you swap a board or a case, check the case’s list of supported boards first. Laptops and all-in-one computers use a board made for that model, so there is no form factor to choose.
Look at the diagram for the parts a technician names. The processor is on the left; everything it reaches is on the right:
The parts a technician names on a PC board, and what joins them to the processor
Text description of the diagram
The diagram has the processor on the left and four things it reaches on the right, each joined by an arrow.
- Memory: DIMM slots on a desktop board, SO-DIMM slots in many laptops, or memory chips soldered to the board. The processor reaches them over its memory channels.
- A PCIe x16 slot, which holds a graphics card, joined to the processor by PCIe lanes.
- Shorter PCIe x4 and x1 slots for add-in cards, which may be reached through the chipset instead of straight from the processor.
- An M.2 socket for an SSD or a Wi-Fi card, joined by PCIe lanes.
Anything fast in that picture is PCI Express. A link is made of PCIe lane: One pair of wires that carries data in each direction between a device and the processor. Links are x1, x4, x8 or x16 lanes wide, and each lane carries more with every PCIe generation., and PCI-SIG lists link widths of 1, 2, 4, 8, 12, 16 and 32 lanes. A graphics card slot is usually x16; an NVMe SSD in an M.2 socket usually has x4. Each generation raises the rate of a lane. The Linux kernel’s own table gives 8 GT/s for generation 3, 16 for generation 4 and 32 for generation 5, each reduced by the 128b/130b encoding, and the program turns that into GB/s for a whole link:
"""How fast is one PCIe link? Data rate per lane and generation, then what a card and a slot negotiate.
The rates and encodings are the table the Linux kernel itself uses (drivers/pci/pci.h, PCIE_SPEED2MBS_ENC): gigatransfers
per second, reduced by the encoding overhead (8b/10b for generations 1 and 2, 128b/130b for 3 to 5).
One lane carries data both ways at once; the figures are for one direction. The card and slot pairs are invented.
"""
# generation: (GT/s per lane, bits of payload, bits sent)
GENERATIONS = {
1: (2.5, 8, 10),
2: (5.0, 8, 10),
3: (8.0, 128, 130),
4: (16.0, 128, 130),
5: (32.0, 128, 130),
}
def gb_per_second(generation, lanes):
"""Usable gigabytes per second in one direction."""
rate, payload, sent = GENERATIONS[generation]
return rate * payload / sent / 8 * lanes
print("One lane, one direction")
print(f"{'gen':>3} {'GT/s':>5} {'encoding':>9} {'GB/s':>6}")
for gen, (rate, payload, sent) in GENERATIONS.items():
print(f"{gen:>3} {rate:>5} {str(payload) + 'b/' + str(sent) + 'b':>9} {gb_per_second(gen, 1):>6.3f}")
print()
print("Whole link, GB/s, one direction")
print(f"{'':>6} {'x1':>6} {'x4':>6} {'x8':>6} {'x16':>6}")
for gen in (3, 4, 5):
print(f"{'gen ' + str(gen):>6} " + " ".join(f"{gb_per_second(gen, w):>6.2f}" for w in (1, 4, 8, 16)))
print()
print("A card and a slot settle on the lower generation and the narrower width")
PAIRS = [
("graphics card, gen 4 x16", (4, 16), "slot, gen 4 x16"),
("graphics card, gen 4 x16", (4, 16), "slot, gen 3 x4"),
("NVMe drive, gen 4 x4", (4, 4), "M.2 socket, gen 3 x4"),
("NVMe drive, gen 3 x4", (3, 4), "M.2 socket, gen 4 x4"),
]
SLOTS = {"slot, gen 4 x16": (4, 16), "slot, gen 3 x4": (3, 4), "M.2 socket, gen 3 x4": (3, 4), "M.2 socket, gen 4 x4": (4, 4)}
for card, (card_gen, card_lanes), slot in PAIRS:
slot_gen, slot_lanes = SLOTS[slot]
gen, lanes = min(card_gen, slot_gen), min(card_lanes, slot_lanes)
print(f"{card} in {slot}: gen {gen} x{lanes} = {gb_per_second(gen, lanes):.2f} GB/s") Output
One lane, one direction
gen GT/s encoding GB/s
1 2.5 8b/10b 0.250
2 5.0 8b/10b 0.500
3 8.0 128b/130b 0.985
4 16.0 128b/130b 1.969
5 32.0 128b/130b 3.938
Whole link, GB/s, one direction
x1 x4 x8 x16
gen 3 0.98 3.94 7.88 15.75
gen 4 1.97 7.88 15.75 31.51
gen 5 3.94 15.75 31.51 63.02
A card and a slot settle on the lower generation and the narrower width
graphics card, gen 4 x16 in slot, gen 4 x16: gen 4 x16 = 31.51 GB/s
graphics card, gen 4 x16 in slot, gen 3 x4: gen 3 x4 = 3.94 GB/s
NVMe drive, gen 4 x4 in M.2 socket, gen 3 x4: gen 3 x4 = 3.94 GB/s
NVMe drive, gen 3 x4 in M.2 socket, gen 4 x4: gen 3 x4 = 3.94 GB/s
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 pcie_links.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
A generation 4 link of four lanes carries 7.88 GB/s in one direction, and sixteen lanes carry 31.51 GB/s. The last
four lines show the rule behind most “why is it slow” tickets: a card and a slot settle on the lower generation and the
narrower width of the two, which PCI-SIG’s commitment to backward compatibility makes possible. A generation 4 drive in
a generation 3 socket works at 3.94 GB/s. On Linux, lspci -nn lists the devices on these links, and its vendor and
device numbers are hexadecimal; the number base converter turns them into decimal.
An M.2 socket: A small card socket on a board for SSDs, Wi-Fi cards and similar modules. Depending on the board it is wired for PCIe, SATA or both, so its manual says what it accepts. is the small card socket for SSDs and Wi-Fi cards. Depending on the board it is wired for PCIe, for SATA or for both, so the board’s manual says what it accepts; the keys and the choice between NVMe and SATA belong to storage drives and RAID. A graphics card also draws power through its own cables, which power supplies, UPS sizing and battery safety covers.
A faster card in a faster slot
Press Edit and add ("graphics card, gen 5 x16", (5, 16), "slot, gen 4 x16") to PAIRS. The link settles at
generation 4 and sixteen lanes, 31.51 GB/s, even though the card could do twice that.
Checkpoint
Check: Form factors, PCIe lanes and M.2 sockets
Integrated graphics share memory, graphics cards bring their own VRAM
The graphics chip comes in two kinds. integrated graphics: A graphics unit built into the processor chip. It has no memory of its own and draws on the computer's main memory, unlike a graphics card. sit inside the processor and use the computer’s main memory. A graphics card or a separate graphics chip has its own memory, called VRAM: Video RAM: the memory on a graphics card, used for textures, frames and models. An application's video memory requirement usually means this dedicated memory, not the system's RAM.. The Mac’s graphics report is the integrated case at its clearest: the chipset is the Apple M5 Pro, it has 20 cores and sits on the built-in bus, and the report prints no VRAM line, because the graphics draw on the same unified 48 GB as the CPU. A Windows laptop with a Radeon 780M inside its processor, as AMD’s 7840HS sheet lists, is the same idea on x86-64.
So “the application needs 4 GB of video memory” is a question about which pool the maker means. Read the wording: a requirement for dedicated video memory is met only by a card or chip with that much of its own; a requirement that allows shared memory can be met by integrated graphics if the system has memory to share. Laptops often have both kinds of chip, and the inventory lists two adapters.
The inventory has its own trap. In Microsoft’s Win32_VideoController class the AdapterRAM property is a uint32
in bytes, and a 32-bit number cannot hold more than 4,294,967,295, one byte short of 4 GiB. So a card with 8 GB still
reports about 4 GB. The program reads a sample record with two adapters and applies that rule:
"""'The application needs 4 GB of video memory': what Windows reports, and what it cannot report.
SAMPLE RECORD (invented values, in the format of
Get-CimInstance Win32_VideoController | Format-List Name, AdapterRAM). AdapterRAM is a 32-bit field in bytes, so the
largest number it can hold is 2**32 - 1 bytes, just under 4 GiB, whatever the card really has.
"""
RECORD = """Name : AMD Radeon(TM) 780M Graphics
AdapterRAM : 536870912
Name : NVIDIA GeForce RTX 4070 Laptop GPU
AdapterRAM : 4293918720
"""
NEEDS_GIB = 4
FIELD_MAX = 2**32 - 1 # the most a uint32 can hold, in bytes
FULL = 4_000_000_000 # at or above this the field is treated as full (a card with 4 GiB or more)
GIB = 2**30
print(f"largest value of the field: {FIELD_MAX:,} bytes = {FIELD_MAX / GIB:.3f} GiB")
print(f"the application needs {NEEDS_GIB} GiB of video memory")
print()
adapters, current = [], {}
for line in RECORD.splitlines():
if not line.strip():
continue
key, value = (part.strip() for part in line.split(":", 1))
current[key] = value
if key == "AdapterRAM":
adapters.append(current)
current = {}
for adapter in adapters:
size = int(adapter["AdapterRAM"])
gib = size / GIB
if size >= FULL:
verdict = "field is full: the card has 4 GiB or more, so read its real size from its specification"
elif size < GIB:
verdict = f"under the {NEEDS_GIB} GiB asked for: probably integrated graphics that share system memory"
else:
verdict = f"{gib:.1f} GiB of its own memory"
print(f"{adapter['Name']}")
print(f" AdapterRAM {size:,} bytes = {gib:.2f} GiB -> {verdict}") Output
largest value of the field: 4,294,967,295 bytes = 4.000 GiB the application needs 4 GiB of video memory AMD Radeon(TM) 780M Graphics AdapterRAM 536,870,912 bytes = 0.50 GiB -> under the 4 GiB asked for: probably integrated graphics that share system memory NVIDIA GeForce RTX 4070 Laptop GPU AdapterRAM 4,293,918,720 bytes = 4.00 GiB -> field is full: the card has 4 GiB or more, so read its real size from its specification
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 vram_check.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
The first adapter reports 512 MiB, a small carve-out that marks integrated graphics. The second reports 4,293,918,720 bytes, which is 4.00 GiB: the field is full, so the true size must come from the card’s specification, and the program says so rather than claiming a 4 GB card.
Change the second card
Press Edit and set the second AdapterRAM to 3221225472, which is 3 GiB. The verdict changes to “3.0 GiB of its
own memory”, because the value is now below the full field and can be trusted.
One slip turns this field, and the word “memory”, into a wrong answer to the ticket itself:
Counting system memory as video memory
Wrong: “The laptop has 32 GB of RAM, so 4 GB of VRAM is no problem.” Right: system RAM and a card’s VRAM are different pools. With integrated graphics the system RAM is shared, so the requirement’s wording decides the answer.
Checkpoint
Check: Integrated graphics and video memory
Reading the same facts on Windows, macOS and Linux
Every system answers the same four questions in its own words. Step through the commands, system by system; the boxes stay the same and the line under each changes:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- Four facts, three dialects. Every hardware ticket needs the CPU, its cores, the memory and the graphics chip. Windows, macOS and Linux each print them in their own words; the four boxes are the facts.
- Windows. PowerShell reads the system through Get-CimInstance. WMIC used to do this and is removed from Windows 11 version 24H2 and later, so scripts that call it need changing.
- macOS. Terminal reads the same facts with sysctl and system_profiler. The lesson ran these on a real Mac: they print Apple M5 Pro, 18 cores and 51,539,607,552 bytes.
- Linux. lscpu prints the CPU and its cores, free -b prints memory in bytes, and lspci lists the PCI devices, the graphics chip among them. In a virtual machine lscpu shows the guest, not the physical host.
- One record at the end. Whatever the system, the answer fits one record: CPU family, cores, logical processors and memory in bytes. The next example parses all three dialects into that shape.
On Windows, Get-CimInstance reads a WMI class by name: Win32_Processor for the CPU name, Architecture, cores and
logical processors, and Win32_PhysicalMemory for the modules. Its Capacity is in bytes for each module, and Microsoft
points to it for an accurate figure because Win32_ComputerSystem.TotalPhysicalMemory may not be accurate when the
firmware uses some of the memory. In Architecture, 9 means x64 and 12 means ARM64. The old wmic tool is gone from
Windows 11 version 24H2 and later, and Microsoft’s note says it is no longer available as a feature on demand, so a
script that calls it needs the Get-CimInstance form. On Linux, lscpu prints the architecture, model name and cores,
free -b prints memory in bytes (-h uses units of 1,024), and lspci lists the PCI devices, the graphics chip among
them.
The program below reads four records into one shape. The macOS record is the real session text of this lesson. The other three are sample records in the format the Windows and Linux commands print, with invented values, since nothing was captured from those machines:
"""Four sample inventory records, read into one shape.
The macOS record is what the lesson's session printed on a real Mac. The other three are SAMPLE RECORDS: text in the
format the Windows and Linux commands print, with invented but plausible values (nothing was captured from a machine
for them). The point is that one parser can turn the three dialects into the same four facts.
"""
import json
MACOS = """$ sysctl -n machdep.cpu.brand_string
Apple M5 Pro
$ sysctl -n hw.physicalcpu
18
$ sysctl -n hw.logicalcpu
18
$ sysctl -n hw.memsize
51539607552
$ uname -m
arm64
"""
# Get-CimInstance Win32_Processor | Format-List Name, Architecture, NumberOfCores, NumberOfLogicalProcessors
# Get-CimInstance Win32_ComputerSystem | Format-List TotalPhysicalMemory
WINDOWS_X64 = """Name : AMD Ryzen 7 7840HS w/ Radeon 780M Graphics
Architecture : 9
NumberOfCores : 8
NumberOfLogicalProcessors : 16
TotalPhysicalMemory : 33822867456
"""
WINDOWS_ARM = """Name : Snapdragon(R) X Elite - X1E78100 - Qualcomm(R) Oryon(TM) CPU
Architecture : 12
NumberOfCores : 12
NumberOfLogicalProcessors : 12
TotalPhysicalMemory : 16642998272
"""
# lscpu, then free -b
LINUX = """Architecture: x86_64
CPU(s): 12
Model name: 12th Gen Intel(R) Core(TM) i5-12400
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 1
total used free shared buff/cache available
Mem: 16358903808 2412974080 9893113856 214958080 4052815872 13483347968
Swap: 2147479552 0 2147479552
"""
FAMILY = {"arm64": "arm64", "aarch64": "arm64", "x86_64": "x86-64", "9": "x86-64", "12": "arm64"}
def fields(text):
"""Every 'key : value' or 'key: value' line of a record, as a dict."""
found = {}
for line in text.splitlines():
if ":" in line:
key, value = line.split(":", 1)
found[key.strip()] = value.strip()
return found
def parse_inventory(text, os_name):
if os_name == "macos":
lines = text.splitlines()
answer = {lines[i][2:]: lines[i + 1] for i in range(len(lines) - 1) if lines[i].startswith("$ ")}
return {
"cpu": answer["sysctl -n machdep.cpu.brand_string"],
"family": FAMILY[answer["uname -m"]],
"cores": int(answer["sysctl -n hw.physicalcpu"]),
"logical": int(answer["sysctl -n hw.logicalcpu"]),
"memory_bytes": int(answer["sysctl -n hw.memsize"]),
}
if os_name == "windows":
f = fields(text)
return {
"cpu": f["Name"],
"family": FAMILY[f["Architecture"]],
"cores": int(f["NumberOfCores"]),
"logical": int(f["NumberOfLogicalProcessors"]),
"memory_bytes": int(f["TotalPhysicalMemory"]),
}
if os_name == "linux":
f = fields(text)
mem_line = next(line for line in text.splitlines() if line.startswith("Mem:"))
return {
"cpu": f["Model name"],
"family": FAMILY[f["Architecture"]],
"cores": int(f["Core(s) per socket"]) * int(f["Socket(s)"]),
"logical": int(f["CPU(s)"]),
"memory_bytes": int(mem_line.split()[1]),
}
raise ValueError(f"unknown system: {os_name!r}")
RECORDS = [
("macOS (real)", MACOS, "macos"),
("Windows x64 (sample)", WINDOWS_X64, "windows"),
("Windows on Arm (sample)", WINDOWS_ARM, "windows"),
("Linux (sample)", LINUX, "linux"),
]
print(f"{'record':<24} {'family':<7} {'cores':>5} {'logical':>7} {'memory':>9} cpu")
for label, text, name in RECORDS:
r = parse_inventory(text, name)
gib = r["memory_bytes"] / 2**30
print(f"{label:<24} {r['family']:<7} {r['cores']:>5} {r['logical']:>7} {gib:>6.1f} GiB {r['cpu']}")
print()
print(json.dumps(parse_inventory(MACOS, "macos"), indent=2)) Output
record family cores logical memory cpu
macOS (real) arm64 18 18 48.0 GiB Apple M5 Pro
Windows x64 (sample) x86-64 8 16 31.5 GiB AMD Ryzen 7 7840HS w/ Radeon 780M Graphics
Windows on Arm (sample) arm64 12 12 15.5 GiB Snapdragon(R) X Elite - X1E78100 - Qualcomm(R) Oryon(TM) CPU
Linux (sample) x86-64 6 12 15.2 GiB 12th Gen Intel(R) Core(TM) i5-12400
{
"cpu": "Apple M5 Pro",
"family": "arm64",
"cores": 18,
"logical": 18,
"memory_bytes": 51539607552
}
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 inventory.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
The table shows why the record has both a core count and a logical count: the Windows x64 sample runs 16 threads on 8
cores, while the Mac and the Windows on Arm sample run one thread per core. Memory in the Windows sample reads 31.5 GiB
from TotalPhysicalMemory, half a gibibyte below the 32 GiB of its two modules; that gap is the reason to add up the
Capacity lines in the practice exercise.
Turn threads off
Press Edit and change NumberOfLogicalProcessors in WINDOWS_X64 to 8, then run it. The logical column drops to
8, which is what a processor with SMT disabled in the firmware reports.
Checkpoint
Check: Inventory commands on three systems
Practise: one parser for three systems
A fleet inventory script has to read what each system prints before it can compare them. Write that parser for the
three dialects of this lesson. The Windows text lists one Capacity line per memory module, so the memory is the sum of
those lines, the exact figure that Microsoft recommends. Then check yourself on the whole lesson.
Exercise · Medium · Python
Read three systems' inventory into one record
Write parse_inventory(text, os_name) so that the text a system printed about its processor and memory becomes one record. os_name is "macos", "windows" or "linux"; any other value raises ValueError. The function returns a dictionary with these keys:
cpu: the processor name, as printed.family:"arm64"or"x86-64".cores: the number of physical cores, a whole number.logical: the number of logical processors (threads), a whole number.memory_gib: the installed memory in GiB (bytes divided by 2**30), rounded to one decimal.
The three texts are shaped like this:
- macos: the output of five commands, each line starting
$and followed by its answer on the next line:sysctl -n machdep.cpu.brand_string,sysctl -n hw.physicalcpu,sysctl -n hw.logicalcpu,sysctl -n hw.memsizeanduname -m(which printsarm64orx86_64). - windows:
Name,Architecture,NumberOfCoresandNumberOfLogicalProcessorsof the processor askey : valuelines (Architectureis9for x64 and12for ARM64), then oneCapacity : <bytes>line for each memory module. The memory is the **sum of all theCapacitylines**. - linux:
lscpulines such asArchitecture:,CPU(s):,Model name:,Core(s) per socket:andSocket(s):(x86_64oraarch64), then theMem:line offree -b, whose first number is the total in bytes. The physical cores areCore(s) per sockettimesSocket(s).
Starter code · inventory.py
def parse_inventory(text, os_name):
"""Return {"cpu", "family", "cores", "logical", "memory_gib"} for the text a system printed."""
return {} The sample tests · test_inventory.py
from inventory import parse_inventory
MACOS = """$ sysctl -n machdep.cpu.brand_string
Apple M5 Pro
$ sysctl -n hw.physicalcpu
18
$ sysctl -n hw.logicalcpu
18
$ sysctl -n hw.memsize
51539607552
$ uname -m
arm64
"""
WINDOWS = """Name : AMD Ryzen 7 7840HS w/ Radeon 780M Graphics
Architecture : 9
NumberOfCores : 8
NumberOfLogicalProcessors : 16
Capacity : 17179869184
Capacity : 17179869184
"""
WINDOWS_ARM = """Name : Snapdragon(R) X Elite - X1E78100 - Qualcomm(R) Oryon(TM) CPU
Architecture : 12
NumberOfCores : 12
NumberOfLogicalProcessors : 12
Capacity : 17179869184
"""
LINUX = """Architecture: x86_64
CPU(s): 12
Model name: 12th Gen Intel(R) Core(TM) i5-12400
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 1
total used free shared buff/cache available
Mem: 16358903808 2412974080 9893113856 214958080 4052815872 13483347968
Swap: 2147479552 0 2147479552
"""
def test_macos_record():
"""reads the five commands of a Mac into one record"""
assert parse_inventory(MACOS, "macos") == {
"cpu": "Apple M5 Pro", "family": "arm64", "cores": 18, "logical": 18, "memory_gib": 48.0,
}
def test_windows_adds_the_modules():
"""adds up the Capacity of every memory module"""
record = parse_inventory(WINDOWS, "windows")
assert record["memory_gib"] == 32.0
assert (record["family"], record["cores"], record["logical"]) == ("x86-64", 8, 16)
assert record["cpu"] == "AMD Ryzen 7 7840HS w/ Radeon 780M Graphics"
def test_windows_on_arm():
"""maps architecture 12 to arm64 and reads a single module"""
record = parse_inventory(WINDOWS_ARM, "windows")
assert record["family"] == "arm64"
assert record["memory_gib"] == 16.0
def test_linux_cores_are_cores_times_sockets():
"""multiplies the cores of a socket by the sockets and takes the total of free -b"""
assert parse_inventory(LINUX, "linux") == {
"cpu": "12th Gen Intel(R) Core(TM) i5-12400", "family": "x86-64", "cores": 6, "logical": 12,
"memory_gib": 15.2,
}
def test_unknown_system():
"""refuses a system other than macos, windows or linux"""
try:
parse_inventory(MACOS, "plan9")
except ValueError:
return
raise AssertionError("parse_inventory(text, 'plan9') should raise ValueError") A hint
Split the work by system first. For macOS, pair each $ line with the line after it and look the answers up by their command. For Windows and Linux, read every key : value line into a dictionary, but keep the Capacity lines of Windows in a list, because the same key appears once for each module. Convert the bytes to GiB last, once.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Practice that adapts to you
Practise this lesson
13 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up (fresher): what do “8 cores, 16 threads” mean on a specification sheet, and how do you read both on a Windows PC?
Cores are physical processing units. Threads, which Windows calls logical processors, are the streams of work the
operating system can schedule. A processor with simultaneous multithreading, which Intel calls hyperthreading, runs two
threads on each core, so 8 cores give 16 threads. Those two threads share one core’s execution units, so the gain is
real but less than double. On Windows, Get-CimInstance Win32_Processor lists NumberOfCores and
NumberOfLogicalProcessors. If the cores are fewer than the logical processors, multithreading is on, and the logical
count only includes threads that are enabled. In a ticket I write both numbers beside the CPU name and its family, for
example “x86-64, 8 cores, 16 threads”, because licences, benchmarks and sizing advice each use a different one.
Two harder questions follow, one on an Intel-only app and the next macOS release, one on a workstation that got slower after a memory upgrade. Sketch what you would check first in each, then read the model answer:
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Fresher to mid
An office has 30 Macs: 20 Apple silicon, 10 Intel. A finance app is Intel-only, and its vendor has not said whether an Apple silicon version is coming. Apple says Rosetta will be limited in the next major macOS release. What do you do over the coming months, and what do you tell the finance team now?
-
Mid to senior
A workstation user says it feels slower since a technician added a second memory stick. The old stick was 16 GB DDR4-3200; the new one is 8 GB DDR4-2666 from another maker, and the system now reports 24 GB. Is the upgrade the cause? How do you check, and what do you change?
Flashcards · 7 cards
Recall it, then check
Say the answer to yourself before you look: recalling it is what makes it stick.
-
Which three readings does a hardware ticket come down to?
What the machine has fitted now, what the exact model's specification allows, and the arithmetic that joins the two into a plan.
-
Which three facts describe a CPU in a ticket?
Its family, x86-64 or Arm64, its physical cores and its logical processors, written together, as in Arm64, 18 cores, 18 threads, rather than a bare 18-core.
-
What do 8 cores and 16 threads mean on a specification sheet?
Eight physical processing units, each running two hardware threads through simultaneous multithreading, which Intel calls hyperthreading. Windows shows the 16 threads as logical processors. Two threads share one core, so the gain is less than double.
-
What does instruction-set emulation cover on an Arm64 computer, and what does it not?
It translates apps built for x86-64 so that they run, as Windows on Arm does for x64 apps and Rosetta does for Intel apps on a Mac. Drivers are not covered: they must be built for the processor family itself.
-
What has to match when memory is added to a computer?
The form, DIMM or SO-DIMM, since soldered memory cannot be changed at all, and the type, since DDR4 and DDR5 do not mix. Matched modules across two channels move about twice the data, and ECC works only when processor, board and modules all support it.
-
A PCIe card and its slot differ in generation and width. How fast does the pair run?
At the lower generation and the narrower width of the two.
-
Why can a 32-bit AdapterRAM reading never show more than 4 GiB of video memory?
A 32-bit value cannot count past 4 GiB. Read the requirement's wording too: integrated graphics share main memory, while a graphics card brings its own VRAM.
Key takeaways
- A hardware ticket becomes three readings: what the machine has fitted, what the exact model’s specification allows, and the arithmetic that joins them into a plan.
- The CPU family (x86-64 or Arm64) decides which builds run, emulation covers apps but not drivers, and a CPU is described by its family, its cores and its logical processors.
- Memory has a form (DIMM, SO-DIMM or soldered), a type that cannot be swapped between DDR4 and DDR5, channels that reward matched modules, and an optional ECC that the whole platform must support.
- The board’s form factor, PCIe lanes and M.2 sockets set what can be added, and a card and a slot run at the lower generation and the narrower width of the two.
- Integrated graphics share main memory and a card has its own VRAM, so a video-memory requirement is answered by its
wording, and a 32-bit
AdapterRAMcan never show more than 4 GiB. - Windows, macOS and Linux print the same four facts in different commands, and one parser can turn them into one record.
Terms in this lesson
- Arm64
- The 64-bit Arm processor family of Apple silicon Macs, Windows on Arm laptops, phones and many servers. Software built only for x86-64 needs translation to run on it.
- CPU core
- One physical processing unit inside a processor. A chip with 8 cores can run 8 programs at the same moment, or 16 threads when each core runs two.
- DIMM
- A dual in-line memory module: the full-size stick of memory used in desktop computers and servers. One module goes into one slot on the motherboard.
- ECC memory
- Memory that stores extra check bits with the data, typically 8 for every 64, so the system can correct a single flipped bit. The processor, board and modules must all support it.
- instruction-set emulation
- Software that translates a program built for one processor family so that it runs on another, such as x64 apps on Windows on Arm or Intel apps through Rosetta on a Mac.
- integrated graphics
- A graphics unit built into the processor chip. It has no memory of its own and draws on the computer's main memory, unlike a graphics card.
- logical processor
- A hardware thread that the operating system can schedule work on. With hyperthreading or SMT each core shows two, so 8 cores can report 16 logical processors.
- M.2 socket
- A small card socket on a board for SSDs, Wi-Fi cards and similar modules. Depending on the board it is wired for PCIe, SATA or both, so its manual says what it accepts.
- memory channel
- An independent path between the processor and its memory. Modules fitted in matched pairs across two channels move about twice the data of one module on one channel.
- motherboard form factor
- The standard that fixes a board's size, mounting holes and layout, such as ATX, microATX or mini-ITX, so that boards and cases from different makers fit together.
- PCIe lane
- One pair of wires that carries data in each direction between a device and the processor. Links are x1, x4, x8 or x16 lanes wide, and each lane carries more with every PCIe generation.
- SO-DIMM
- A small outline DIMM: the shorter memory module used in many laptops, mini PCs and all-in-one computers. It is not interchangeable with a full-size DIMM.
- unified memory
- One pool of memory, in the processor's package, that the CPU and the graphics unit share. Its size is set by the configuration chosen when the Mac is bought.
- VRAM
- Video RAM: the memory on a graphics card, used for textures, frames and models. An application's video memory requirement usually means this dedicated memory, not the system's RAM.
- x86-64
- The processor family of Intel and AMD chips in most Windows PCs, many Linux machines and older Macs. Software built for it does not run on Arm64 chips without translation.
References
- Get-CimInstance (CimCmdlets) (Microsoft)
- Win32_Processor class (Microsoft)
- Win32_PhysicalMemory class (Microsoft)
- Win32_ComputerSystem class (Microsoft)
- Win32_VideoController class (Microsoft)
- Deprecated features in the Windows client (Microsoft)
- How emulation works on Arm (Microsoft)
- Using Intel-based apps on a Mac with Apple silicon (Apple)
- Apple unleashes M1 (Apple)
- lscpu(1), Linux manual page (Linux man-pages project)
- free(1), Linux manual page (Linux man-pages project)
- lspci(8), manual page of the PCI Utilities (PCI Utilities project)
- AMD Ryzen 7 7700 specifications (AMD)
- AMD Ryzen 7 7840HS specifications (AMD)
- DDR5 DRAM and its frequently asked questions (Micron Technology)
- DDR5 DRAM (Samsung Semiconductor)
- Error Detection And Correction (EDAC) devices (The Linux Kernel documentation)
- drivers/pci/pci.h, PCIE_SPEED2MBS_ENC (The Linux kernel source)
- PCI-SIG frequently asked questions (PCI-SIG)
- ATX Specification, version 2.2 (Intel Corporation (archived copy))
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress