Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.4 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. membnch.c
  5. Abstract:
  6. Short benchmark for testing raw memory throughput of
  7. SMP machines. Designed to thrash the hell out of the
  8. system's memory bus.
  9. Author:
  10. John Vert (jvert) 12-Sep-1994
  11. Revision History:
  12. --*/
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. typedef struct _THREADPARAMS {
  17. DWORD ThreadIndex;
  18. PCHAR BufferStart;
  19. ULONG BufferLength;
  20. DWORD Stride;
  21. } THREADPARAMS, *PTHREADPARAMS;
  22. DWORD MemorySize = 64*1024*1024;
  23. HANDLE StartEvent;
  24. THREADPARAMS ThreadParams[32];
  25. HANDLE ThreadHandle[32];
  26. ULONG TotalIterations = 1;
  27. DWORD WINAPI
  28. MemoryTest(
  29. IN LPVOID lpThreadParameter
  30. );
  31. main (argc, argv)
  32. int argc;
  33. char *argv[];
  34. {
  35. DWORD CurrentRun;
  36. DWORD i;
  37. SYSTEM_INFO SystemInfo;
  38. PCHAR Memory;
  39. PCHAR ThreadMemory;
  40. DWORD ChunkSize;
  41. DWORD ThreadId;
  42. DWORD StartTime, EndTime;
  43. DWORD ThisTime, LastTime;
  44. DWORD IdealTime;
  45. LONG IdealImprovement;
  46. LONG ActualImprovement;
  47. DWORD StrideValues[] = {4, 16, 32, 4096, 8192, 0};
  48. LPDWORD Stride = StrideValues;
  49. BOOL Result;
  50. //
  51. // If we have an argument, use that as the # of iterations
  52. //
  53. if (argc > 1) {
  54. TotalIterations = atoi(argv[1]);
  55. if (TotalIterations == 0) {
  56. fprintf(stderr, "Usage: %s [# iterations]\n",argv[0]);
  57. exit(1);
  58. }
  59. printf("%d iterations\n",TotalIterations);
  60. }
  61. //
  62. // Determine how many processors in the system.
  63. //
  64. GetSystemInfo(&SystemInfo);
  65. //
  66. // Create the start event.
  67. //
  68. StartEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  69. if (StartEvent == NULL) {
  70. fprintf(stderr, "CreateEvent failed, error %d\n",GetLastError());
  71. exit(1);
  72. }
  73. //
  74. // Try and boost our working set size.
  75. //
  76. do {
  77. Result = SetProcessWorkingSetSize(GetCurrentProcess(), MemorySize, MemorySize*2);
  78. if (!Result) {
  79. MemorySize -= 10*1024*1024;
  80. }
  81. } while ( !Result );
  82. printf("MEMBNCH: Using %d MB array\n", MemorySize / (1024*1024));
  83. //
  84. // Allocate a big chunk of memory (64MB)
  85. //
  86. Memory = VirtualAlloc(NULL,
  87. MemorySize,
  88. MEM_COMMIT,
  89. PAGE_READWRITE);
  90. if (Memory==NULL) {
  91. fprintf(stderr, "VirtualAlloc failed, error %d\n",GetLastError());
  92. exit(1);
  93. }
  94. do {
  95. printf("STRIDE = %d\n", *Stride);
  96. for (CurrentRun=1; CurrentRun<=SystemInfo.dwNumberOfProcessors; CurrentRun++) {
  97. printf(" %d threads: ", CurrentRun);
  98. //
  99. // Start the threads, and let them party on the
  100. // memory buffer.
  101. //
  102. ResetEvent(StartEvent);
  103. ChunkSize = (MemorySize / CurrentRun) & ~7;
  104. for (i=0; i<CurrentRun; i++) {
  105. ThreadParams[i].ThreadIndex = i;
  106. ThreadParams[i].BufferStart = Memory + (i * ChunkSize);
  107. ThreadParams[i].BufferLength = ChunkSize;
  108. ThreadParams[i].Stride = *Stride;
  109. ThreadHandle[i] = CreateThread(NULL,
  110. 0,
  111. MemoryTest,
  112. &ThreadParams[i],
  113. 0,
  114. &ThreadId);
  115. if (ThreadHandle[i] == NULL) {
  116. fprintf(stderr, "CreateThread %d failed, %d\n", i, GetLastError());
  117. exit(1);
  118. }
  119. }
  120. //
  121. // Touch all the pages.
  122. //
  123. ZeroMemory(Memory, MemorySize);
  124. //
  125. // Start the threads and wait for them to exit.
  126. //
  127. StartTime = GetTickCount();
  128. SetEvent(StartEvent);
  129. WaitForMultipleObjects(CurrentRun, ThreadHandle, TRUE, INFINITE);
  130. EndTime = GetTickCount();
  131. ThisTime = EndTime-StartTime;
  132. printf("%7d ms",ThisTime);
  133. printf(" %.3f MB/sec",(float)(MemorySize*TotalIterations)/(1024*1024) / ((float)ThisTime / 1000));
  134. if (CurrentRun > 1) {
  135. IdealTime = (LastTime * (CurrentRun-1)) / CurrentRun;
  136. IdealImprovement = LastTime - IdealTime;
  137. ActualImprovement = LastTime - ThisTime;
  138. printf(" (%3d %% )\n",(100*ActualImprovement)/IdealImprovement);
  139. } else {
  140. printf("\n");
  141. }
  142. LastTime = ThisTime;
  143. for (i=0; i<CurrentRun; i++) {
  144. CloseHandle(ThreadHandle[i]);
  145. }
  146. }
  147. ++Stride;
  148. } while ( *Stride );
  149. }
  150. DWORD WINAPI
  151. MemoryTest(
  152. IN LPVOID lpThreadParameter
  153. )
  154. {
  155. PTHREADPARAMS Params = (PTHREADPARAMS)lpThreadParameter;
  156. ULONG i;
  157. ULONG j;
  158. DWORD *Buffer;
  159. ULONG Stride;
  160. ULONG Length;
  161. ULONG Iterations;
  162. Buffer = (DWORD *)Params->BufferStart;
  163. Stride = Params->Stride / sizeof(DWORD);
  164. Length = Params->BufferLength / sizeof(DWORD);
  165. WaitForSingleObject(StartEvent,INFINITE);
  166. for (Iterations=0; Iterations < TotalIterations; Iterations++) {
  167. for (j=0; j < Stride; j++) {
  168. for (i=0; i < Length-Stride; i += Stride) {
  169. Params->BufferStart[i+j] += 1;
  170. }
  171. }
  172. }
  173. }