Repository navigation
Conversation
The Windows heap serves blocks past its large-block threshold straight from VirtualAlloc and frees them back to the OS. On Windows the editor preview allocates two frame-sized buffers per frame (the RGBA readback and the frame_image BGRA copy), so playback mapped, zero-faulted and unmapped a full frame of pages twice per frame. mimalloc reuses its freed segments. Adds examples/frame-alloc-benchmark.rs, which runs that per-frame buffer pattern under both allocators.
Contributor
|
@divik-05 is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
diiviikk5
marked this pull request as ready for review
October 26, 2026 15:58
| assert!(!readback.is_null() && !converted.is_null()); | ||
| readback.write_bytes(0x40, padded.size()); | ||
| converted.copy_from_nonoverlapping(readback, tight.size()); | ||
| black_box(converted.read_volatile()); |
Contributor
There was a problem hiding this comment.
Benchmark can skip buffer work
Only one byte reaches black_box. read_volatile() preserves that byte's read, not the writes and copy across the remaining megabytes. Release builds could therefore report better timings and fewer page faults because the compiler skips work, not because the allocator improved. Pass the complete initialized output slice to black_box before freeing the buffers.
Suggested change
| black_box(converted.read_volatile()); | |
| black_box(std::slice::from_raw_parts(converted, tight.size())); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/examples/frame-alloc-benchmark.rs
Line: 33
Comment:
**Benchmark can skip buffer work**
Only one byte reaches `black_box`. `read_volatile()` preserves that byte's read, not the writes and copy across the remaining megabytes. Release builds could therefore report better timings and fewer page faults because the compiler skips work, not because the allocator improved. Pass the complete initialized output slice to `black_box` before freeing the buffers.
```suggestion
black_box(std::slice::from_raw_parts(converted, tight.size()));
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.…-alloc-benchmark Passing one byte to black_box left the optimizer free to drop the fill and copy of the rest of the buffer. Hand it the full slice instead.
This branch has not been deployed
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.
On Windows the editor preview uses the RGBA path, which allocates two frame-sized buffers for every presented frame:
PendingReadback::wait(crates/rendering/src/frame_pipeline.rs) starts a freshVecon the preview path. Only exports recycle it.frame_image(apps/desktop-gpui/src/editor_window.rs) allocates a tight BGRA copy throughunpad_rgba_to_bgra.Each is 3.5 MB at the default half-size preview and 8 MB at 1080p. The Windows heap serves blocks that large directly from
VirtualAllocand returns them on free, so every frame pays demand-zero page faults on both buffers. mimalloc keeps freed segments resident and reuses them.This sets mimalloc as the global allocator on Windows only. macOS and Linux are unchanged.
Numbers
examples/frame-alloc-benchmark.rs(added here) repeats that per-frame pattern against each allocator: padded readback, tight copy, both written in full and then freed. 600 frames per case after 30 warm-up frames, 10 runs, Ryzen 5 4600H, Windows 11 26200:Medians, with min–max across the 10 runs in brackets. This is a laptop, so the timings are noisy. The fault counts are not: they varied by at most 3 across all runs, and at half size 1737 is every 4 KB page of both buffers, every frame. They matched the earlier version of this benchmark, which only passed one byte to
black_box, so that version was not skipping work.What I haven't measured is end-to-end playback (process CPU, fps, working set) in the app itself. My Windows machine can't build the full app yet (
ortneeds MSVC 14.42+). If someone can run the A/B below on Windows, that would settle how much of this reaches playback. Expect a somewhat higher steady working set, since mimalloc keeps segments mapped.Related
Only Rust allocations change. FFmpeg, D3D/wgpu and the OS keep their own heaps.