/*++ Copyright (c) 1994 Microsoft Corporation Module Name: membnch.c Abstract: Short benchmark for testing raw memory throughput of SMP machines. Designed to thrash the hell out of the system's memory bus. Author: John Vert (jvert) 12-Sep-1994 Revision History: --*/ #include #include #include typedef struct _THREADPARAMS { DWORD ThreadIndex; PCHAR BufferStart; ULONG BufferLength; DWORD Stride; } THREADPARAMS, *PTHREADPARAMS; DWORD MemorySize = 64*1024*1024; HANDLE StartEvent; THREADPARAMS ThreadParams[32]; HANDLE ThreadHandle[32]; ULONG TotalIterations = 1; DWORD WINAPI MemoryTest( IN LPVOID lpThreadParameter ); main (argc, argv) int argc; char *argv[]; { DWORD CurrentRun; DWORD i; SYSTEM_INFO SystemInfo; PCHAR Memory; PCHAR ThreadMemory; DWORD ChunkSize; DWORD ThreadId; DWORD StartTime, EndTime; DWORD ThisTime, LastTime; DWORD IdealTime; LONG IdealImprovement; LONG ActualImprovement; DWORD StrideValues[] = {4, 16, 32, 4096, 8192, 0}; LPDWORD Stride = StrideValues; BOOL Result; // // If we have an argument, use that as the # of iterations // if (argc > 1) { TotalIterations = atoi(argv[1]); if (TotalIterations == 0) { fprintf(stderr, "Usage: %s [# iterations]\n",argv[0]); exit(1); } printf("%d iterations\n",TotalIterations); } // // Determine how many processors in the system. // GetSystemInfo(&SystemInfo); // // Create the start event. // StartEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (StartEvent == NULL) { fprintf(stderr, "CreateEvent failed, error %d\n",GetLastError()); exit(1); } // // Try and boost our working set size. // do { Result = SetProcessWorkingSetSize(GetCurrentProcess(), MemorySize, MemorySize*2); if (!Result) { fprintf(stderr, "teeny weenie little machine, couldn't set working set to %08lx\n",MemorySize); MemorySize -= 10*1024*1024; } } while ( !Result ); // // Allocate a big chunk of memory (64MB) // Memory = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE); if (Memory==NULL) { fprintf(stderr, "VirtualAlloc failed, error %d\n",GetLastError()); exit(1); } do { printf("STRIDE = %d\n", *Stride); for (CurrentRun=1; CurrentRun<=SystemInfo.dwNumberOfProcessors; CurrentRun++) { printf(" %d threads: ", CurrentRun); // // Start the threads, and let them party on the // memory buffer. // ResetEvent(StartEvent); ChunkSize = (MemorySize / CurrentRun) & ~7; for (i=0; i 1) { IdealTime = (LastTime * (CurrentRun-1)) / CurrentRun; IdealImprovement = LastTime - IdealTime; ActualImprovement = LastTime - ThisTime; printf(" (%3d %% )\n",(100*ActualImprovement)/IdealImprovement); } else { printf("\n"); } LastTime = ThisTime; for (i=0; iBufferStart; Stride = Params->Stride / sizeof(DWORD); Length = Params->BufferLength / sizeof(DWORD); WaitForSingleObject(StartEvent,INFINITE); for (Iterations=0; Iterations < TotalIterations; Iterations++) { for (j=0; j < Stride; j++) { for (i=0; i < Length-Stride; i += Stride) { Params->BufferStart[i+j] += 1; } } } }