Add a Win64 fast path for in-place small-block ReallocMem#98
Open
janrysavy wants to merge 1 commit into
Open
Conversation
janrysavy
marked this pull request as ready for review
July 21, 2026 09:44
Owner
|
Hi Jan, Thank you for the report. Those numbers look very appealing. I took a look at the disassembly of the Pascal code under X64 and the number of register pushes onto the stack certainly seem excessive - particularly when compared to the handwritten X86 BASM code. I think what I'm going to do is to "inline" the in-place small block resize for all targets and split off separate calls for the slow upsize/downsize calls. I like to keep the code for all paths as similar as possible - makes it easier to maintain, and also to compare behaviour and spot bugs. It's not a quick change, so please bear with me. Pierre |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Win32 already handles the common small-block in-place
ReallocMemcase in assembly. On Win64, the dispatcher enters the PascalFastMM_ReallocMem_ReallocSmallBlockhelper even when it can immediately return the original pointer. This change routes an in-use small block to a short out-of-line assembly path while leaving medium-block, large-block, debug-block, and invalid-pointer dispatch unchanged. In the 100-pair confirmation of a 64-byte to 63-byte resize, throughput improved by 49.90% on AMD and 14.65% on Intel. The new path performs the existing manager and size-policy checks and returns directly for the common case. Upsizes and moving downsizes tail-jump to the unchanged Pascal helper. Win32 andPurePascalpaths are unchanged.Tracking issue: #99
Benchmark
The benchmark repeatedly resizes an allocated 64-byte small block to 63 bytes without moving it. Retained 100-pair runs measured +49.90% on AMD (95% CI +49.83% to +50.01%) and +14.65% on Intel (+13.84% to +15.82%). Forced upsizes measured -1.08% on AMD and -0.86% on Intel; moving downsizes measured -2.50% and -1.66%, respectively. The medium and large controls ranged from -0.16% to +0.80%. Avoiding the slow-path losses would require rewriting more of the Pascal helper; this patch leaves that helper unchanged. Win32 is unchanged.
Each result uses 100 alternating baseline/candidate process pairs after three warmups. Throughput gain is
(baseline time / candidate time - 1) * 100, with a deterministic 10,000-resample bootstrap interval for the paired median. Tests ran on an AMD Ryzen 9 7950X and an Intel Core i7-8750H under Windows 11 build 26200, using Delphi Win64 37.0.59082.6021 with release-style-O+builds. The Intel runs use fewer operations to keep process duration similar; a failed worker-affinity request aborts the run.Correctness
FastMMReallocTest.dprpasses for DCC 37 baseline and candidate Win32/Win64 builds on both CPUs. Additional compatibility runs pass with DCC 35 and 36 Win32/Win64 and with DCC 37PurePascal. For requested sizes from 2 through 2600 bytes, the test checks in-place downsizing, pointer identity, upsizing, and data preservation. It also covers both size-policy boundaries, required moves, medium/large/debug dispatch, and invalid or freed-pointer error paths.Full benchmark source, raw AMD and Intel samples, summaries, and correctness tests: https://github.com/janrysavy/FastMM5/tree/ed3229e678bbe4b2455b8435168442d51f430996/perf-review
Scope
This targets applications that frequently call
ReallocMemwithout crossing a small-block size-policy boundary. The measured microbenchmark gain ranged from 14.65% on Intel to 49.90% on AMD; it is not an estimate of whole-application performance.