Virtual Memory Benchmark
#ifdef BENCHMARK_HAS_CXX11 | |
#undef BENCHMARK_HAS_CXX11 | |
#endif | |
#include <benchmark/benchmark.h> | |
#include <windows.h> | |
static constexpr size_t MemorySize = 0x10'000 * 4800; /* 300 MiB */ | |
/* #define MEMSET \ */ | |
/* do { \ */ | |
/* for (int i = 0; i < 4800; ++i) \ */ | |
/* benchmark::DoNotOptimize(*((char *)mem + (i * 0x10'000)) = 1); \ */ | |
/* benchmark::ClobberMemory(); \ */ | |
/* } while (0) */ | |
#define MEMSET \ | |
do { \ | |
benchmark::DoNotOptimize(memset(mem, 0xFD, MemorySize)); \ | |
benchmark::ClobberMemory(); \ | |
} while (0) | |
static void | |
BM_VMemMemset(benchmark::State &state) | |
{ | |
void *mem = VirtualAlloc( | |
nullptr, | |
MemorySize, | |
MEM_RESERVE | MEM_COMMIT, | |
PAGE_READWRITE); | |
for (auto _ : state) { | |
((void)_); | |
MEMSET; | |
} | |
VirtualFree(mem, 0, MEM_RELEASE); | |
} | |
static void | |
BM_VMemAllocFree(benchmark::State &state) | |
{ | |
for (auto _ : state) { | |
((void)_); | |
void *mem = VirtualAlloc( | |
nullptr, | |
MemorySize, | |
MEM_RESERVE | MEM_COMMIT, | |
PAGE_READWRITE); | |
/* | |
* Theoretically, the cost of the allocation will be | |
* seen on first access of the range. This is going to get ignored | |
* here. | |
*/ | |
MEMSET; | |
VirtualFree(mem, 0, MEM_RELEASE); | |
} | |
} | |
static void | |
BM_VMemDecommit(benchmark::State &state) | |
{ | |
void *mem = VirtualAlloc( | |
nullptr, | |
MemorySize, | |
MEM_RESERVE, | |
PAGE_READWRITE); | |
for (auto _ : state) { | |
((void)_); | |
VirtualAlloc(mem, MemorySize, MEM_COMMIT, PAGE_READWRITE); | |
MEMSET; | |
VirtualFree(mem, MemorySize, MEM_DECOMMIT); | |
} | |
VirtualFree(mem, 0, MEM_RELEASE); | |
} | |
static void | |
BM_VMemDecommitReset(benchmark::State &state) | |
{ | |
void *mem = VirtualAlloc( | |
nullptr, | |
MemorySize, | |
MEM_RESERVE | MEM_COMMIT, | |
PAGE_READWRITE); | |
VirtualAlloc(mem, MemorySize, MEM_RESET, PAGE_READWRITE); | |
for (auto _ : state) { | |
((void)_); | |
VirtualAlloc(mem, MemorySize, MEM_RESET_UNDO, PAGE_READWRITE); | |
MEMSET; | |
VirtualAlloc(mem, MemorySize, MEM_RESET, PAGE_READWRITE); | |
} | |
VirtualFree(mem, 0, MEM_RELEASE); | |
} | |
static void | |
BM_VMemDecommitMap(benchmark::State &state) | |
{ | |
LARGE_INTEGER s; | |
s.QuadPart = MemorySize; | |
HANDLE hMapping = CreateFileMappingA( | |
INVALID_HANDLE_VALUE, | |
0, | |
PAGE_READWRITE, | |
s.HighPart, | |
s.LowPart, | |
NULL); | |
for (auto _ : state) { | |
((void)_); | |
void *mem = MapViewOfFileEx( | |
hMapping, | |
FILE_MAP_ALL_ACCESS, | |
0, | |
0, | |
MemorySize, | |
nullptr); | |
MEMSET; | |
UnmapViewOfFile(mem); | |
} | |
CloseHandle(hMapping); | |
} | |
BENCHMARK(BM_VMemMemset); | |
BENCHMARK(BM_VMemAllocFree); | |
BENCHMARK(BM_VMemDecommit); | |
BENCHMARK(BM_VMemDecommitReset); | |
BENCHMARK(BM_VMemDecommitMap); | |
int | |
main(int argc, char** argv) | |
{ | |
/* Initialize benchmarks */ | |
::benchmark::Initialize(&argc, argv); | |
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) | |
return 1; | |
::benchmark::RunSpecifiedBenchmarks(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment