Fork of irusanov/ZenTimings · v1.40 → v1.44
Open source · GPL-3.0ZenTimings (fork)
ZenTimings (opens in a new tab) is irusanov's tool for viewing memory timings on Ryzen systems, and a lot of people use it. I forked it in July 2026 and added live sensors, a memory benchmark, OC tools, and reading of the tCCD_L family on DDR5.
Between 26 July and 16 August 2026 I published ten releases, two of them betas. The fork is 18 commits ahead of upstream, with 17,691 lines added across 80 files.
Auto-update is switched off on purpose. Pulling an upstream release would overwrite the changes made here.
What the fork adds
Monitoring
Live CPU Die and DDR5 DIMM temperatures on the main window, with small history charts and minimum, maximum and average values. DIMM power summed from the PMICs, I/O die temperature on Zen 5 and Ryzen 7000, a WHEA error count, CSV telemetry logging, and a tray icon that can show the hottest temperature.
Timings
tCCD_L, tCCD_L_WR and tCCD_L_WR2. CA, CK and CS on-die termination per bank group (ODT A and ODT B). SPD-rated timings next to the running ones. An “All” view with every channel side by side.
Benchmark
Read, write, copy and latency for L1, L2, L3 and RAM. On CPUs with two CCDs, each L3 gets its own row. A random-access score that brings out the bank-cycle timings (tRAS, tRC, tRRD, tFAW). History with a pinnable baseline, and HTML export.
OC tools
OC profile management and OC tools windows, and comparison with reference profiles.
Convenience
Turkish user interface, a Ctrl+Alt+S screenshot hotkey named after the memory configuration, and start with Windows. If something crashes, a crash.txt with the cause is left next to the exe.
Reading tCCD_L
On DDR5, tCCD_L is the shortest time between two back-to-back read or write commands to the same bank group. It can be set in the BIOS, but ZenStates-Core didn't read these values.
In v1.40 I decoded tCCD_L and tCCD_L_WR2 from UMC registers that ZenStates-Core doesn't read: tCCD_L from 0x50198[7:3] + 5, tCCD_L_WR2 from 0x502E0[5:0] + 7. tCCD_L_WR isn't in any UMC register. Two dumps that differed only in that value were byte-identical across both channel windows, the AOD table and the SPD.
The value lives in the APOB, the data AGESA leaves in memory at boot. The three same-bank-group write timings are stored one after another, one copy per channel. I find them by anchoring on tCCD_L and tCCD_L_WR2 instead of a fixed offset.
Then it turned out that register and APOB offsets change from board to board and from one AGESA version to the next, and between Zen 4 and Zen 5 too. v1.42 fixed the readout on some MSI boards. In v1.42.6 I moved all three values to the APOB, and v1.42.7 hardened the lookup. Since v1.43, values that fall back to the register readout are marked with “!”. v1.44 has another fix for the newest BIOSes with AGESA 1.3.0.1c.
Because every BIOS can keep the values somewhere else, the fastest fix for a wrong readout is two debug reports, one taken before changing tCCD_L in the BIOS and one after. A fix to the APOB layout also went into ZenStates-Core (f8dce5b (opens in a new tab)).
Getting the benchmark right
The first benchmark had a bug. A buffer larger than about 305 MiB was never fully walked, so the 512 and 1024 MB runs measured a smaller area than asked for and reported a better latency than they should have. I fixed it in v1.41.
An ordinary loop written in C# can't measure a cache. On a Zen+ core a scalar loop gave 28.5 GB/s from L1d, 28.6 from L2 and 27.8 from L3. Three nearly identical numbers meant the loop was being measured, not the cache.
.NET Framework has no SIMD intrinsics, so the read, write and copy loops are generated as machine code at run time. The memory page is first mapped writable and filled, then made executable, never both at once. The code isn't used until it passes a self-test that writes and reads back known bytes.
Which width is faster depends on the processor, so the app runs both widths and uses the faster one. On a 9800X3D, L1d reads measured 150 GB/s at 128 bits, 322 at 256 bits and 672 at 512 bits. That gain exists only on Zen 5. Zen 4 issues one 512-bit load per cycle, the same as two 256-bit loads, and Zen 1 to 3 have no AVX-512 at all.
The DRAM write score uses non-temporal stores. An ordinary store first reads a cache line it doesn't own from memory and writes it back later. That's 128 bytes of traffic for 64 bytes of data, and it halves the write results.
The measurement is now pinned to a quiet core, uses large memory pages and samples in short slices. It reports a noise verdict with the result. The app's own polling pauses during a run. If large pages can't be used, the app says why, and a “What to do?” button walks through the fix.
Changelog
From the release notes on GitHub and the fork's changelog file (WPF/Changelog.txt), newest first. Each version links to its GitHub release.
- Release notes on GitHub (v1.44, opens in a new tab)
New
- The memory benchmark now also measures your CPU caches: speed and latency for L1, L2, L3 and RAM, all in one table.
- On CPUs with two chiplets (7950X3D, 9950X3D …), each L3 cache gets its own row, and the row shows how many cores measured it (e.g. “8 of 16”).
- A Re-run button and a progress bar on the results tab, so you don't have to switch back to run again.
- A new 2048 MB buffer option for CPUs with very large caches.
- Benchmark history with a pinnable baseline. Click any old run to see exactly what got faster or slower.
- One-click HTML export that shares your full result, with a screenshot of your timings next to the scores.
- I/O die temperature for Zen 5 and Ryzen 7000, with a switch in Options.
- If anything ever crashes, the app leaves a crash.txt next to the exe so the cause can be found.
Changed
- Results are much steadier between runs. The app finds and uses the best core automatically.
- If the benchmark can't use large memory pages, it tells you why, and a “What to do?” button walks you through the fix.
- Your benchmark history can no longer be lost if the file gets corrupted. It is rescued instead of overwritten.
- If your RAM overclock is unstable, the benchmark reports a memory error instead of crashing. That's your answer, not a bug.
Fixed
- SoC voltage no longer shows a false 1.55 V while HWiNFO or other monitoring tools are running.
- tCCD_L timings should now read correctly on the newest BIOSes (AGESA 1.3.0.1c). The release note says “I hope”.
Note
- These release notes also sum up some changes that first came in v1.43, such as the benchmark history and the HTML export.
- Release notes on GitHub (v1.43.0, opens in a new tab)
New
- A new Random score that brings out the bank-cycle timings (tRAS, tRC, tRRD, tFAW).
- A benchmark history panel with a pinnable baseline, and an HTML export that puts the ZenTimings window next to the scores.
- A new “All” button next to the module selector shows every channel's timings side by side. Each column is headed with the module's PMIC, rank, DRAM die and capacity.
- A new IOD readout on Zen 5: I/O die temperature and its hotspot, with a switch in Options.
- System Info now lists tCCD_L, tCCD_L_WR and tCCD_L_WR2 under Memory Timings and APOB Table.
Changed
- The memory benchmark was reworked: a native buffer with automatic large pages, pinned to a quiet core, short-slice sampling with a noise verdict. App polling pauses during a run.
- Benchmark ceilings now scale with the CCD count and the number of populated channels.
- DIMM temperature and power now share one readout instead of two labelled entries.
- The clock ratio now sits on UCLK alone, as 1:1 or 1:2 against MCLK. MCLK and FCLK no longer carry one.
- Exports (JSON, HTML, OC profiles) now carry the full tCCD_L family.
- tCCD_L values that fall back to the register readout are marked with “!”.
- The HTML debug report is dark now. Printing it still comes out white.
- The Turkish interface now also covers the benchmark window.
- The Options window scrolls when it's taller than the screen.
- Benchmark runs recorded before this release are marked “not comparable” instead of getting a baseline delta.
Fixed
- Many bug fixes.
Note
- CPU VDDIO above about 1.45 V shows N/A. This is expected and can't be fixed for now, because the firmware zeroes the only field that carries the value.
Beta, to check whether CPU VDDIO matches the value in the BIOS.
Release notes on GitHub (v1.42.8-beta, opens in a new tab)Changed
- Removed unused hardware monitor libraries from the package.
Fixed
- Fixed CPU VDDIO showing 0.0000 V or a swapped value on some AGESA versions.
- MEM VDDQ and MEM VPP no longer swap on boards without PMIC telemetry.
Beta, to report whether tCCD_L, tCCD_L_WR and tCCD_L_WR2 match the BIOS. If v1.42.6 works on your system, don't use this version.
Release notes on GitHub (v1.42.7-beta, opens in a new tab)New
- tCCD_L_WR now shows in OC Tools.
Changed
- Hardened the tCCD_L APOB lookup.
- Release notes on GitHub (v1.42.6, opens in a new tab)
Changed
- tCCD_L, tCCD_L_WR and tCCD_L_WR2 now come from the APOB instead of the UMC registers.
Note
- If it still reads wrong on your board, two debug reports, one before and one after changing tCCD_L in the BIOS, are the fastest way to get it fixed.
- Release notes on GitHub (v1.42, opens in a new tab)
Fixed
- Fixed the tCCD_L readout on some MSI motherboards and AGESA versions.
Note
- As the release note put it, this would either fix the tCCD_L readout or break it completely. Every register and APOB offset differs from board to board and from one AGESA version to another (Zen 4 vs Zen 5 as well), so finding the exact location is really hard.
- Release notes on GitHub (v1.41.5, opens in a new tab)
New
- CPU Die temperature, memory temperature, DIMM power and the WHEA error count can each be switched on or off in Options → Readouts.
- Release notes on GitHub (v1.41.1, opens in a new tab)
Fixed
- Screenshot bug fixes.
- Release notes on GitHub (v1.41, opens in a new tab)
New
- Turkish interface for the Options window (Options → Language).
Changed
- Clearer names: “Reference Profiles” in the menu and “My Profiles” in OC Tools. Logging is now “Start / Stop CSV Logging”.
Fixed
- Fixed ProcDqsOdt showing the ProcDqOdt value on DDR5 APU boards.
- Memory benchmark: a buffer larger than about 305 MiB was never fully walked, so the 512 and 1024 MB runs measured a smaller working set than asked for and reported a better latency than the label implied.
- CSV logging now writes through to the disk, so a hard lock-up keeps the rows around the freeze instead of losing them with the OS cache.
- The telemetry window no longer folds a frozen reading into its min/max/average while the main window is minimized.
- System Info no longer risks taking the app down on platforms without an AOD table.
The first release of the fork: live sensors, benchmarks and the tCCD_L family.
Release notes on GitHub (v1.40, opens in a new tab)NewMonitoring
- Live CPU Die and DDR5 DIMM temperatures on the main window, each with a sparkline of its recent history and a min/max/avg tooltip.
- Total DIMM power, summed from the on-module PMICs.
- The tray icon can show the hottest temperature in a colour of your choice. It is drawn at the shell's real icon size, so it stays sharp on scaled displays.
- CSV telemetry logging and WHEA error monitoring.
NewTimings
- tCCD_L and tCCD_L_WR2, decoded from UMC registers that ZenStates-Core does not read: tCCD_L from
0x50198[7:3] + 5, tCCD_L_WR2 from0x502E0[5:0] + 7. - tCCD_L_WR, recovered from the APOB. It appears in no UMC register, and it is located by anchoring on tCCD_L and tCCD_L_WR2 rather than on a fixed offset.
- CA, CK and CS on-die termination per bank group (ODT A and ODT B).
- SPD-rated timings next to the running ones, with per-timing tooltips.
- The timings panel was rebalanced so all three columns end on the same row.
NewBenchmarks and OC
- Memory bandwidth and latency tests with a dedicated results window.
- Persistent benchmark history and comparison with reference profiles.
- OC profile management and OC tools windows.
NewConvenience
- Turkish user interface (Options → Language).
- A Ctrl+Alt+S screenshot hotkey, named after the current memory configuration.
- Start with Windows.
Note
- An unofficial fork of ZenTimings. Auto-update is switched off on purpose, because pulling an upstream release would overwrite these changes.
What went upstream
- ZenTimings PR #106 (opens in a new tab): all channels side by side, and a read-only debug report window. Merged on 19 September 2026.
- ZenStates-Core PR #27 (opens in a new tab): code that parses the report version, core count and per-module timings from debug reports. Merged on 17 September 2026.
- ZenStates-Core f8dce5b (opens in a new tab): the APOB layout for the Zen 5 APU extended block and CCDL was corrected, with a thank-you to me in the commit (4 September 2026).
- ZenStates-Core 05f9100 (opens in a new tab): I noticed some PM table offsets were shifted, and irusanov updated the table (21 September 2026).
Known issues
- CPU VDDIO above about 1.45 V shows N/A. The firmware zeroes the only field that carries the value, so this can't be fixed for now.
- The tCCD_L family can still read wrong on some board and BIOS combinations. Values that fall back to the register readout are marked with “!”.