├── Makefile ├── README.md └── wtime.c /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # GNU Makefile for windows benchmark tool wtime.exe 3 | # /TR 2017-05-19 4 | ############################################################################## 5 | 6 | # mingw 7 | CROSS32 = i686-w64-mingw32- 8 | CROSS64 = x86_64-w64-mingw32- 9 | 10 | CC = gcc 11 | STRIP = strip 12 | SFLAGS = -R .note -R .comment 13 | 14 | CFLAGS = -W -Wall -pipe -Wno-format 15 | CFLAGS += -fomit-frame-pointer 16 | CFLAGS += -O3 17 | #CFLAGS += -flto 18 | #CFLAGS += -march=native 19 | LDFLAGS = -lwinmm -lpsapi 20 | 21 | PRGS = wtime-w64.exe wtime-w32.exe 22 | OBJS = wtime.c 23 | 24 | all: again 25 | again: clean $(PRGS) 26 | 27 | wtime-w64.exe: 28 | $(CROSS64)$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) 29 | $(CROSS64)$(STRIP) $(SFLAGS) $@ 30 | 31 | wtime-w32.exe: 32 | $(CROSS32)$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) 33 | $(CROSS32)$(STRIP) $(SFLAGS) $@ 34 | 35 | clean: 36 | rm -f $(PRGS) 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Information given by the help option 3 | 4 | ``` 5 | wtime version 1.0a 6 | Copyright (c) 2017 Tino Reichardt 7 | 8 | 9 | Usage: wtime COMMAND [OPTIONS] 10 | 11 | The program will start COMMAND with the given OPTIONS 12 | and print out some statistic of it to stderr. 13 | 14 | There are no options for this command. 15 | 16 | Report bugs to: https://github.com/mcmilk/wtime/issues 17 | ``` 18 | 19 | ## Sample Outputs 20 | 21 | For one thread: 22 | ``` 23 | Command: 7z a silesia.7z -mmt=off -mx15 silesia 24 | 25 | TIMES in milliseconds 26 | RunningTime................. 32104 27 | UserTime.................... 31793 28 | KernelTime.................. 249 29 | 30 | MEMORY in KiB 31 | PageFaultCount.............. 112 32 | PeakWorkingSetSize.......... 34856 33 | WorkingSetSize.............. 20 34 | QuotaPeakPagedPoolUsage..... 85 35 | QuotaPagedPoolUsage......... 0 36 | QuotaPeakNonPagedPoolUsage.. 6 37 | QuotaNonPagedPoolUsage...... 0 38 | PagefileUsage............... 0 39 | PeakPagefileUsage........... 36296 40 | 41 | IO count 42 | ReadOperationCount.......... 81 43 | WriteOperationCount......... 34 44 | OtherOperationCount......... 115 45 | ReadTransferCount........... 211939037 46 | WriteTransferCount.......... 58043652 47 | OtherTransferCount.......... 3414 48 | ``` 49 | 50 | For four threads: 51 | ``` 52 | Command: 7z a silesia.7z -mmt=4 -mx15 silesia 53 | 54 | TIMES in milliseconds 55 | RunningTime................. 11668 56 | UserTime.................... 43025 57 | KernelTime.................. 202 58 | 59 | MEMORY in KiB 60 | PageFaultCount.............. 124 61 | PeakWorkingSetSize.......... 133688 62 | WorkingSetSize.............. 20 63 | QuotaPeakPagedPoolUsage..... 85 64 | QuotaPagedPoolUsage......... 0 65 | QuotaPeakNonPagedPoolUsage.. 7 66 | QuotaNonPagedPoolUsage...... 0 67 | PagefileUsage............... 0 68 | PeakPagefileUsage........... 184848 69 | 70 | IO count 71 | ReadOperationCount.......... 81 72 | WriteOperationCount......... 34 73 | OtherOperationCount......... 115 74 | ReadTransferCount........... 211939037 75 | WriteTransferCount.......... 58043652 76 | OtherTransferCount.......... 3414 77 | ``` 78 | -------------------------------------------------------------------------------- /wtime.c: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Copyright (c) 2017 Tino Reichardt 4 | * All rights reserved. 5 | * 6 | * This source code is licensed under the BSD-style license found in the 7 | * LICENSE file in the root directory of this source tree. An additional grant 8 | * of patent rights can be found in the PATENTS file in the same directory. 9 | * 10 | * You can contact the author at: 11 | * - wtime source repository: https://github.com/mcmilk/wtime 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include /* GetProcessTimes() */ 20 | #include /* GetProcessMemoryInfo() */ 21 | 22 | static void panic(char *errmsg) 23 | { 24 | fprintf(stderr, "%s\n", errmsg); 25 | exit(1); 26 | } 27 | 28 | static void usage(void) 29 | { 30 | printf("\n" 31 | "\n wtime version 1.0a" 32 | "\n Copyright (c) 2017 Tino Reichardt" 33 | "\n" 34 | "\n" 35 | "\n Usage: wtime COMMAND [OPTIONS]" 36 | "\n" 37 | "\n The program will start COMMAND with the given OPTIONS" 38 | "\n and print out some statistic of it to stderr." 39 | "\n" 40 | "\n There are no options for this command." 41 | "\n" 42 | "\n Report bugs to: https://github.com/mcmilk/wtime/issues" 43 | "\n"); 44 | 45 | exit(0); 46 | } 47 | 48 | int main(int argc, char *argv[]) 49 | { 50 | STARTUPINFO si = { }; /* init si to zero */ 51 | PROCESS_INFORMATION pi = { }; 52 | FILETIME createTime, exitTime, kernelTime, userTime; 53 | ULONGLONG Create64, Exit64, Kernel64, User64; 54 | PROCESS_MEMORY_COUNTERS memCounters; 55 | IO_COUNTERS ioCounters; 56 | char *cmdline; 57 | int ret, alen, i; 58 | 59 | /* even this can be difficult, print the usage ;) */ 60 | if (argc < 2) 61 | usage(); 62 | 63 | /* build up our command line for the new process */ 64 | for (i = 1, alen = 0; i < argc; i++) 65 | alen += strlen(argv[i]) + 1; 66 | cmdline = malloc(alen + 1); 67 | if (!cmdline) 68 | panic("Out of memory!\n"); 69 | 70 | cmdline[0] = 0; 71 | for (i = 1; i < argc; i++) { 72 | if (i != 1) 73 | strcat(cmdline, " "); 74 | strcat(cmdline, argv[i]); 75 | } 76 | 77 | /* open process... */ 78 | si.cb = sizeof(si); 79 | if (!CreateProcess 80 | (NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { 81 | fprintf(stderr, "CreateProcess() failed, Error: %d.\n", 82 | GetLastError()); 83 | exit(1); 84 | } 85 | 86 | /* ... wait for finish */ 87 | WaitForSingleObject(pi.hProcess, INFINITE); 88 | 89 | ret = 90 | GetProcessTimes(pi.hProcess, &createTime, &exitTime, 91 | &kernelTime, &userTime); 92 | if (ret == 0) 93 | panic("GetProcessTimes() failed."); 94 | 95 | ret = 96 | GetProcessMemoryInfo(pi.hProcess, &memCounters, 97 | sizeof(memCounters)); 98 | if (ret == 0) 99 | panic("GetProcessMemoryInfo() failed."); 100 | 101 | ret = GetProcessIoCounters(pi.hProcess, &ioCounters); 102 | if (ret == 0) 103 | panic("GetProcessIoCounters() failed."); 104 | 105 | /* let the process close the last handle, now */ 106 | CloseHandle(pi.hProcess); 107 | CloseHandle(pi.hThread); 108 | 109 | /** 110 | * print summary about the infos 111 | */ 112 | fprintf(stderr, "Command: %s\n", cmdline); 113 | 114 | /** 115 | * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683223(v=vs.85).aspx 116 | * 117 | * typedef struct _FILETIME { 118 | * DWORD dwLowDateTime; 119 | * DWORD dwHighDateTime; 120 | * } FILETIME; 121 | */ 122 | 123 | /* get the u64 values */ 124 | Create64 = 125 | ((ULONGLONG) createTime.dwHighDateTime << 32) + 126 | createTime.dwLowDateTime; 127 | Exit64 = 128 | ((ULONGLONG) exitTime.dwHighDateTime << 32) + 129 | exitTime.dwLowDateTime; 130 | Kernel64 = 131 | ((ULONGLONG) kernelTime.dwHighDateTime << 32) + 132 | kernelTime.dwLowDateTime; 133 | User64 = 134 | ((ULONGLONG) userTime.dwHighDateTime << 32) + 135 | userTime.dwLowDateTime; 136 | Exit64 -= Create64; 137 | 138 | #define _MILLISECOND (10000) 139 | fprintf(stderr, 140 | "\nTIMES in milliseconds" 141 | "\nRunningTime................. %llu" 142 | "\nUserTime.................... %llu" 143 | "\nKernelTime.................. %llu" 144 | "\n", 145 | Exit64 / _MILLISECOND, 146 | User64 / _MILLISECOND, 147 | Kernel64 / _MILLISECOND); 148 | 149 | /** 150 | * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx 151 | * 152 | * typedef struct _PROCESS_MEMORY_COUNTERS { 153 | * DWORD cb; 154 | * DWORD PageFaultCount; 155 | * SIZE_T PeakWorkingSetSize; 156 | * SIZE_T WorkingSetSize; 157 | * SIZE_T QuotaPeakPagedPoolUsage; 158 | * SIZE_T QuotaPagedPoolUsage; 159 | * SIZE_T QuotaPeakNonPagedPoolUsage; 160 | * SIZE_T QuotaNonPagedPoolUsage; 161 | * SIZE_T PagefileUsage; 162 | * SIZE_T PeakPagefileUsage; 163 | * } PROCESS_MEMORY_COUNTERS; 164 | */ 165 | 166 | #define _KB (1024) 167 | fprintf(stderr, 168 | "\nMEMORY in KiB" 169 | "\nPageFaultCount.............. %llu" 170 | "\nPeakWorkingSetSize.......... %llu" 171 | "\nWorkingSetSize.............. %llu" 172 | "\nQuotaPeakPagedPoolUsage..... %llu" 173 | "\nQuotaPagedPoolUsage......... %llu" 174 | "\nQuotaPeakNonPagedPoolUsage.. %llu" 175 | "\nQuotaNonPagedPoolUsage...... %llu" 176 | "\nPagefileUsage............... %llu" 177 | "\nPeakPagefileUsage........... %llu" 178 | "\n", 179 | (ULONGLONG)memCounters.PageFaultCount / _KB, 180 | (ULONGLONG)memCounters.PeakWorkingSetSize / _KB, 181 | (ULONGLONG)memCounters.WorkingSetSize / _KB, 182 | (ULONGLONG)memCounters.QuotaPeakPagedPoolUsage / _KB, 183 | (ULONGLONG)memCounters.QuotaPagedPoolUsage / _KB, 184 | (ULONGLONG)memCounters.QuotaPeakNonPagedPoolUsage / _KB, 185 | (ULONGLONG)memCounters.QuotaNonPagedPoolUsage / _KB, 186 | (ULONGLONG)memCounters.PagefileUsage / _KB, 187 | (ULONGLONG)memCounters.PeakPagefileUsage / _KB); 188 | 189 | /** 190 | * https://msdn.microsoft.com/de-de/library/windows/desktop/ms683218(v=vs.85).aspx 191 | * 192 | * typedef struct _IO_COUNTERS { 193 | * ULONGLONG ReadOperationCount; 194 | * ULONGLONG WriteOperationCount; 195 | * ULONGLONG OtherOperationCount; 196 | * ULONGLONG ReadTransferCount; 197 | * ULONGLONG WriteTransferCount; 198 | * ULONGLONG OtherTransferCount; 199 | * } IO_COUNTERS; 200 | */ 201 | 202 | fprintf(stderr, 203 | "\nIO count" 204 | "\nReadOperationCount.......... %llu" 205 | "\nWriteOperationCount......... %llu" 206 | "\nOtherOperationCount......... %llu" 207 | "\nReadTransferCount........... %llu" 208 | "\nWriteTransferCount.......... %llu" 209 | "\nOtherTransferCount.......... %llu" 210 | "\n", 211 | ioCounters.ReadOperationCount, 212 | ioCounters.WriteOperationCount, 213 | ioCounters.OtherOperationCount, 214 | ioCounters.ReadTransferCount, 215 | ioCounters.WriteTransferCount, 216 | ioCounters.OtherTransferCount); 217 | 218 | /* free resources and exit */ 219 | free(cmdline); 220 | exit(0); 221 | } 222 | --------------------------------------------------------------------------------