|
|
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#define DbgPrint printf
#define SEG_1_SIZE 1024 * 1024
#define SEG_X_SIZE 1024 * 1024 * 64
#define VM_MEMMAN_ITERATIONS 150
#define VM_MEMMAN_ITERATIONS2 2000
#define MemManSubtest5Count 200
int TotalBenchMarks = 0; #define MAX_BENCHMARKS 32
char *BenchMarkNames[ MAX_BENCHMARKS ]; ULONG BenchMarkRates[ MAX_BENCHMARKS ]; ULONG BenchMarkFracs[ MAX_BENCHMARKS ];
typedef struct _PERFINFO { LARGE_INTEGER StartTime; LARGE_INTEGER StopTime; PCHAR Title; ULONG Iterations; } PERFINFO, *PPERFINFO;
int StartBenchMark( PCHAR Title, ULONG Iterations, PPERFINFO PerfInfo );
VOID FinishBenchMark( PPERFINFO PerfInfo );
__cdecl main() { PCHAR p1, p2, p3, p4; // pointers into new segment
PCHAR pa[MemManSubtest5Count]; // array for section pointers
PULONG u1; ULONG actual; // actual xfer count for read
ULONG ssize; // section allocation size var
ULONG ii, ix; // loop index variables
PERFINFO PerfInfo; ULONG Seg1Size; ULONG SegxSize; ULONG CommitSize; NTSTATUS status; HANDLE CurrentProcessHandle, Section1; LARGE_INTEGER SectionSize; ULONG Size; ULONG ViewSize;
DbgPrint("NT Memory Management test\n");
CurrentProcessHandle = NtCurrentProcess();
Size = 1024L * 1024L; p1 = NULL;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed allocvm - status %X\n", status); }
for (p2=p1; p2 < (p1 + Size); p2 += 4) { u1 = (PULONG)p2; *u1 = (ULONG)p2; } // for
SectionSize.LowPart = 1024*1024; SectionSize.HighPart = 0; status = NtCreateSection (&Section1, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL);
if (!NT_SUCCESS(status)) { DbgPrint("service failed create sect - status %X\n", status); }
p3 = NULL; ViewSize = 0; status = NtMapViewOfSection (Section1, CurrentProcessHandle, (PVOID *)&p3, 0L, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE );
if (!NT_SUCCESS(status)) { DbgPrint("service failed mapview - status %X\n", status); }
RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
StartBenchMark( "NT MemMan00 -- 1 Meg Copy", 150, &PerfInfo ); //
// Memory Management sub-test 1 --
//
// Create a 1 MB segment with commitment of the pages,
// then touch each page, which should cause a fault and
// a demand zero page to be allocated.
//
//
for (ii=0; ii<150; ii++) {
RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size); }
FinishBenchMark( &PerfInfo );
status = NtClose (Section1);
if (!NT_SUCCESS(status)) { DbgPrint("service failed close sect - status %X\n", status); }
status = NtUnmapViewOfSection (CurrentProcessHandle, p3);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %X\n", status); }
//
// Memory Management sub-test 1 --
//
// Create a 1 MB segment with commitment of the pages,
// then touch each page, which should cause a fault and
// a demand zero page to be allocated.
//
//
StartBenchMark( "NT MemMan01 -- create 1mb section, copy 1mb, delete", 150, &PerfInfo );
for (ii=0; ii<150; ii++) {
status = NtCreateSection (&Section1, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL);
if (!NT_SUCCESS(status)) { DbgPrint("service failed create sect - status %X\n", status); }
p3 = NULL; ViewSize = 0; status = NtMapViewOfSection (Section1, CurrentProcessHandle, (PVOID *)&p3, 0L, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE );
if (!NT_SUCCESS(status)) { DbgPrint("service failed mapview - status %X\n", status); }
RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
p4 = NULL; ViewSize = 0; status = NtMapViewOfSection (Section1, CurrentProcessHandle, (PVOID *)&p4, 0L, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE );
if (!NT_SUCCESS(status)) { DbgPrint("service failed mapview - status %X\n", status); }
status = NtClose (Section1);
if (!NT_SUCCESS(status)) { DbgPrint("service failed close sect - status %X\n", status); }
status = NtUnmapViewOfSection (CurrentProcessHandle, p3);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %X\n", status); }
status = NtUnmapViewOfSection (CurrentProcessHandle, p4);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %X\n", status); } }
FinishBenchMark( &PerfInfo );
//
// Memory Management sub-test 1 --
//
// Create a 1 MB segment with commitment of the pages,
// then touch each page, which should cause a fault and
// a demand zero page to be allocated.
//
//
StartBenchMark( "NT MemMan02 -- alloc 1mb vm, copy 1mb, delete", 150, &PerfInfo );
for (ii=0; ii<150; ii++) {
Size = 1024*1024; p3 = NULL; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, 0, &Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed allocvm - status %X\n", status); }
RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
if (!NT_SUCCESS(status)) { DbgPrint("service failed close sect - status %X\n", status); }
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed freevm - status %X\n", status); }
}
FinishBenchMark( &PerfInfo );
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed freevm - status %X\n", status); }
//
// start regular benchmarks.
//
StartBenchMark( "NT MemMan1 -- 1 Meg Seg, Create, Commit & Touch", VM_MEMMAN_ITERATIONS, &PerfInfo ); //
// Memory Management sub-test 1 --
//
// Create a 1 MB segment with commitment of the pages,
// then touch each page, which should cause a fault and
// a demand zero page to be allocated.
//
//
for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) {
p1 = NULL; Seg1Size = SEG_1_SIZE; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Seg1Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
for (p2=p1; p2 < (p1 + Seg1Size); p2 += 4096) { u1 = (PULONG)p2; *u1=99; // for (ix=0; ix<1023; ix++) {
// u1++;
// if (*u1 != 0) DbgPrint("%lx = %lx\n",u1,*u1);
// }
} // for
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Seg1Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } }
FinishBenchMark( &PerfInfo );
StartBenchMark( "NT MemMan1.5 -- 1 Meg Seg, Create, reserve Commit & Touch", VM_MEMMAN_ITERATIONS, &PerfInfo ); //
// Memory Management sub-test 1 --
//
// Create a 1 MB segment with commitment of the pages,
// then touch each page, which should cause a fault and
// a demand zero page to be allocated.
//
//
for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) {
p1 = NULL; Seg1Size = SEG_1_SIZE; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Seg1Size, MEM_RESERVE | MEM_COMMIT, PAGE_READONLY);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Seg1Size, PAGE_READWRITE, &CommitSize);
if (!NT_SUCCESS(status)) { DbgPrint("service failed (ntprotect)- status %lx\n", status); return 0; }
for (p2=p1; p2 < (p1 + Seg1Size); p2 += 4096) { u1 = (PULONG)p2; *u1=99; // for (ix=0; ix<1023; ix++) {
// u1++;
// if (*u1 != 0) DbgPrint("%lx = %lx\n",u1,*u1);
// }
} // for
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Seg1Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } }
FinishBenchMark( &PerfInfo );
StartBenchMark( "NT MemMan2 -- 1 Meg Seg, Create & Commit Only", VM_MEMMAN_ITERATIONS2, &PerfInfo ); //
// Memory Management sub-test 2 --
//
// Create a 1 MB segment with commitment of the pages,
// but never use the segment.
//
for (ii=0; ii<VM_MEMMAN_ITERATIONS2; ii++) {
p1 = NULL; Seg1Size = SEG_1_SIZE; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Seg1Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Seg1Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
}
FinishBenchMark( &PerfInfo );
StartBenchMark( "NT MemMan3 -- 1 Meg Seg Create Only", VM_MEMMAN_ITERATIONS2, &PerfInfo );
//
// Memory Management sub-test 3 --
//
// Create a 1 MB segment without commitment of the pages,
// but never use or commit the segment.
//
for (ii=0; ii<VM_MEMMAN_ITERATIONS2; ii++) {
p1 = NULL; Seg1Size = SEG_1_SIZE; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Seg1Size, MEM_RESERVE, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Seg1Size, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } }
FinishBenchMark( &PerfInfo );
//
// Reduce the number of iterations on this subtest for now.
// When NT can perform it faster, up the interations again
//
#define VM_MMST04_ITERATIONS 4 //temporarily reduce the iterations
StartBenchMark( "NT MemMan4 -- 64 Meg Seg, Commit Sparse", VM_MMST04_ITERATIONS, &PerfInfo );
//
// Memory Management sub-test 4 --
//
// Create a 64 MB segment without committing the pages,
// then commit and touch at 128 KB intervals.
//
//
for (ii=0; ii<VM_MMST04_ITERATIONS; ii++) {
p1 = NULL; SegxSize = SEG_X_SIZE; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &SegxSize, MEM_RESERVE, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
CommitSize = 4;
for (p2=p1; p2 < (p1 + SegxSize); p2 += 256 * 1024) {
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 0, &CommitSize, MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } if (*p2 != 0) DbgPrint("%lx = %lx\n",p2,*p2); } // for
status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &SegxSize, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); }
} FinishBenchMark( &PerfInfo );
//
StartBenchMark( "NT MemMan5 -- Sparse Section Create/Delete Benchmark", VM_MEMMAN_ITERATIONS, &PerfInfo );
//
// Memory Management sub-test 5 --
//
// Create a alternatively 232k and 112 k memory sections.
// For every 2 created, delete 1. Do this for MemManSubtest5Count times.
//
//
for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) { for (ix=0; ix<MemManSubtest5Count; ix++) { //
// determine if even or odd allocation, if even and not 0, delete a section
//
ssize = (112 * 1024); //assume ODD allocation
if ((ix & 1) == 0) { //if it is an even one
ssize = (232 * 1024); //allocate 232 K on even passes
if (ix){ //except on pass 0
SegxSize = 0; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&pa[ix/2], &SegxSize, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } pa[ix / 2] = 0; //remember this one is gone
} } // end if even allocation
pa[ix] = NULL;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&pa[ix], 0, &ssize, MEM_RESERVE, PAGE_READWRITE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } } // for ix
//
// Now free up the memory used in this test
//
for (ix=0; ix<MemManSubtest5Count; ix++) { if (pa[ix] != 0) { SegxSize = 0; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&pa[ix], &SegxSize, MEM_RELEASE);
if (!NT_SUCCESS(status)) { DbgPrint("service failed - status %lx\n", status); } } // if
} // for
} // for ii
FinishBenchMark( &PerfInfo );
DbgPrint("that's all\n"); return (TRUE);
} int StartBenchMark( PCHAR Title, ULONG Iterations, PPERFINFO PerfInfo ) { DbgPrint( "*** Start %s (%d iterations)\n", PerfInfo->Title = Title, PerfInfo->Iterations = Iterations );
NtQuerySystemTime( (PLARGE_INTEGER)&PerfInfo->StartTime ); return( TRUE ); }
VOID FinishBenchMark( PPERFINFO PerfInfo ) { ULONG TotalMilliSeconds; ULONG IterationsPerSecond; ULONG IterationFractions; LARGE_INTEGER Delta;
NtQuerySystemTime( (PLARGE_INTEGER)&PerfInfo->StopTime );
Delta.QuadPart = PerfInfo->StopTime.QuadPart - PerfInfo->StartTime.QuadPart;
TotalMilliSeconds = Delta.LowPart / 10000;
IterationsPerSecond = (1000 * PerfInfo->Iterations) / TotalMilliSeconds; IterationFractions = (1000 * PerfInfo->Iterations) % TotalMilliSeconds; IterationFractions = (1000 * IterationFractions) / TotalMilliSeconds; if (1) { DbgPrint( " iterations - %9d\n", PerfInfo->Iterations ); DbgPrint( " milliseconds - %9d\n", TotalMilliSeconds ); DbgPrint( " iterations/sec - %5d.%3d\n\n", IterationsPerSecond, IterationFractions ); } BenchMarkNames[ TotalBenchMarks ] = PerfInfo->Title; BenchMarkRates[ TotalBenchMarks ] = IterationsPerSecond; BenchMarkFracs[ TotalBenchMarks ] = IterationFractions; TotalBenchMarks++; }
|