{"id":50871484,"url":"https://github.com/e2b-dev/mem-bench","last_synced_at":"2026-06-15T05:35:05.736Z","repository":{"id":351816067,"uuid":"1211671041","full_name":"e2b-dev/mem-bench","owner":"e2b-dev","description":"Memory Benchmark","archived":false,"fork":false,"pushed_at":"2026-04-17T09:19:23.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-15T05:35:04.744Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/e2b-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T16:20:01.000Z","updated_at":"2026-04-17T09:19:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/e2b-dev/mem-bench","commit_stats":null,"previous_names":["e2b-dev/mem-bench"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/e2b-dev/mem-bench","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e2b-dev%2Fmem-bench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e2b-dev%2Fmem-bench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e2b-dev%2Fmem-bench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e2b-dev%2Fmem-bench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/e2b-dev","download_url":"https://codeload.github.com/e2b-dev/mem-bench/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e2b-dev%2Fmem-bench/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34349925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-15T05:35:04.997Z","updated_at":"2026-06-15T05:35:05.724Z","avatar_url":"https://github.com/e2b-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mem-bench\n\nLinux memory benchmark suite measuring the throughput of various memory-copy\nmechanisms and the latency of page faults across different memory backings.\n\nAll benchmarks are built on [Criterion](https://github.com/bheisler/criterion.rs)\nand produce HTML reports with throughput plots and cross-run regression detection.\n\n---\n\n## Benchmark suites\n\n### `memcpy` — copy throughput\n\nMeasures how fast data can be moved between memory regions using five different\nkernel/userspace mechanisms. Each benchmark is parameterised over **copy size**\nand, where applicable, **page size** (standard 4 KiB vs huge 2 MiB).\n\n| Benchmark | Source | Destination | Mechanism |\n|---|---|---|---|\n| `process_vm_readv` | child process mmap | local mmap | `process_vm_readv(2)` |\n| `mmap_to_file` | anonymous mmap | regular file | `pwrite(2)` |\n| `mmap_to_mmap` | anonymous mmap | anonymous mmap | `memcpy` |\n| `fd_to_fd` | regular file | regular file | `sendfile(2)` |\n| `memfd_to_mmap` | memfd | anonymous mmap | `pread(2)` |\n\n**Sizes tested** (default): 4 KiB, 64 KiB, 1 MiB, 16 MiB, 256 MiB, 1 GiB,\n4 GiB, 16 GiB, 30 GiB.\n\n**Huge page variants** are available for all benchmarks except `fd_to_fd`\n(file page-cache always uses regular pages). Huge page benchmarks skip sizes\nbelow 16 MiB (the first multiple of the 2 MiB huge-page size in the list).\n\n**`process_vm_readv`** forks a child process that allocates the source region\nand then sleeps; the parent reads from it across the process boundary. The child\nis killed and reaped at the end of each benchmark case.\n\n**`mmap_to_file` / `fd_to_fd`** create files on the filesystem pointed to by\n`BENCH_DIR` (see [Configuration](#configuration)) so they reflect real\nfilesystem behaviour rather than tmpfs.\n\n---\n\n### `page_fault` — page-fault latency\n\nMeasures the time to fault in a fixed number of pages (`N_FAULT_PAGES = 128`)\nafter `MADV_DONTNEED` strips them from the process's page table. The\n`MADV_DONTNEED` call is outside the timed region; only the subsequent page\naccesses are measured.\n\n`write_volatile` is used (rather than a read) so that:\n- anonymous accesses allocate a real page instead of mapping the shared zero-page;\n- file/memfd accesses trigger a copy-on-write fault from the page cache.\n\nParameterised over **backing** × **page size**:\n\n| Backing | Standard (4 KiB) | Huge (2 MiB) |\n|---|---|---|\n| `anon` — anonymous private pages | ✓ | ✓ |\n| `file` — regular on-disk file (`BENCH_DIR`) | ✓ | — |\n| `memfd` — `memfd_create` / tmpfs | ✓ | ✓ |\n\n`file + huge` is not supported: mapping a plain file with `MAP_HUGETLB`\nrequires the file to reside on a hugetlbfs mount.\n\n**Throughput** is reported as page faults per second (criterion label:\n`elements/s`). Invert to get average latency per fault.\n\nRegion sizes:\n- Standard: 128 × 4 KiB = 512 KiB\n- Huge: 128 × 2 MiB = 256 MiB (requires 256 MiB of pre-allocated huge pages)\n\n---\n\n## Running\n\n```sh\n# Run both suites\ncargo bench\n\n# Run a single suite\ncargo bench --bench memcpy\ncargo bench --bench page_fault\n\n# Filter by benchmark group or case (criterion name filter)\ncargo bench --bench memcpy -- mmap_to_mmap\ncargo bench -- \"page_fault/memfd/2m\"\n```\n\nHTML reports are written to `target/criterion/report/index.html` and updated\nautomatically on every run, including cross-run regression comparisons.\n\n```sh\nxdg-open target/criterion/report/index.html\n```\n\n---\n\n## Configuration\n\nAll options are set via environment variables.\n\n### `BENCH_DIR`\n\nDirectory used for **real on-disk files** (`mmap_to_file`, `fd_to_fd`,\n`page_fault/file`). Defaults to the current working directory.\n\nSet this to a mount point to benchmark a specific filesystem:\n\n```sh\nBENCH_DIR=/mnt/nvme  cargo bench --bench memcpy -- mmap_to_file\nBENCH_DIR=/mnt/hdd   cargo bench --bench memcpy -- fd_to_fd\n```\n\nFiles are created as anonymous temporaries (unlinked immediately) and cleaned\nup automatically.\n\n### `BENCH_SIZE` *(memcpy suite only)*\n\nRestrict the `memcpy` suite to one or more copy sizes instead of sweeping all\nsizes. Accepts a comma-separated list of values; each value is either a raw byte\ncount or a number with a `KB`, `MB`, or `GB` suffix.\n\n```sh\nBENCH_SIZE=1GB             cargo bench --bench memcpy\nBENCH_SIZE=256MB,1GB,4GB   cargo bench --bench memcpy\nBENCH_SIZE=256MB           cargo bench --bench memcpy -- mmap_to_mmap\nBENCH_SIZE=4096            cargo bench --bench memcpy   # raw bytes\n```\n\n### Huge pages\n\nHuge-page benchmarks require 2 MiB huge pages to be pre-allocated in the\nkernel's hugetlb pool. Check the current pool:\n\n```sh\ncat /proc/sys/vm/nr_hugepages          # number of pre-allocated pages\ncat /proc/meminfo | grep HugePages\n```\n\nAllocate enough pages (example: 512 pages = 1 GiB):\n\n```sh\necho 512 | sudo tee /proc/sys/vm/nr_hugepages\n```\n\nFor the largest `page_fault/huge` case (256 MiB) at least **128** pages are\nneeded. For the largest `memcpy` huge-page case (30 GiB source + destination)\nat least **30720** pages are needed per mapping.\n\nHuge-page benchmarks will `assert!`-fail at startup if the pool is exhausted.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe2b-dev%2Fmem-bench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fe2b-dev%2Fmem-bench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe2b-dev%2Fmem-bench/lists"}