status update, probably last commit
[rofl0r-kripto.git] / perf / perf.h
blob0942170720552b6d48f76f343a8445c3a2635ca5
1 /*
2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
7 *
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
14 #include <stdio.h>
16 #if defined(PERF_UNIX)
18 #include <unistd.h>
19 #include <sched.h>
20 #include <time.h>
22 #elif defined(PERF_WINDOWS)
24 #include <windows.h>
25 #include <PowrProf.h>
26 #include <ntstatus.h>
28 #endif
30 #if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
31 #define PERF_RDTSC
32 #endif
34 #if defined(PERF_WINDOWS) || defined(PERF_RDTSC)
36 #include <stdint.h>
38 typedef uint64_t perf_int;
39 #define PERF_INT_MAX UINT64_MAX
41 #else
43 #include <time.h>
45 typedef clock_t perf_int;
46 #define PERF_INT_MAX (clock_t)UINT64_MAX
48 #endif
50 inline perf_int perf_clock(void)
52 #if defined(PERF_WINDOWS) && defined(PERF_QPC)
54 LARGE_INTEGER x;
56 QueryPerformanceCounter(&x);
58 return x.QuadPart;
60 #elif defined(PERF_RDTSC)
62 uint32_t hi;
63 uint32_t lo;
65 __asm__ __volatile__
67 "cpuid\n"
68 "rdtsc"
69 : "=a"(lo), "=d"(hi)
70 : "a"(0)
71 : "%ebx", "%ecx"
74 return (((uint64_t)hi) << 32) | lo;
76 #elif defined(_POSIX_CPUTIME)
78 struct timespec x;
80 if(clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &x))
81 perror("clock_gettime()");
83 return (((uint64_t)x.tv_sec) << 32) | x.tv_nsec;
85 #else
87 return clock();
89 #endif
92 #if defined(PERF_AVG)
94 #define PERF_START \
95 { \
96 unsigned int i; \
97 cycles = perf_clock(); \
98 for(i = 0; i < 1000000; i++) \
101 #define PERF_STOP \
103 cycles = (perf_clock() - cycles) / 1000000; \
106 #else
108 #define PERF_START \
110 perf_int t0; \
111 perf_int t1; \
112 unsigned int i; \
113 cycles = PERF_INT_MAX; \
114 for(i = 0; i < 1000000; i++) \
116 t0 = perf_clock();
118 #define PERF_STOP \
119 t1 = perf_clock() - t0 - perf_c; \
120 if(cycles > t1) cycles = t1; \
124 #endif
126 perf_int perf_c;
128 void perf_init(void)
130 perf_int cycles;
132 #if defined(PERF_UNIX)
134 struct sched_param p;
136 #ifdef _GNU_SOURCE
137 cpu_set_t set;
139 /* lock process to one core */
140 CPU_ZERO(&set);
141 CPU_SET(0, &set);
142 if(sched_setaffinity(0, CPU_ALLOC_SIZE(1), &set))
143 perror("sched_setaffinity()");
144 #endif
146 puts("For better results disable dynamic CPU frequency scaling!");
148 /* set highest possible priority */
149 for(p.sched_priority = sched_get_priority_max(SCHED_FIFO);
150 p.sched_priority; p.sched_priority--)
152 if(!sched_setscheduler(0, SCHED_FIFO, &p)) break;
154 printf("SCHED_FIFO with priority: %u\n", p.sched_priority);
156 #elif defined(PERF_WINDOWS)
158 SYSTEM_POWER_CAPABILITIES s;
160 /* disable dynamic CPU frequency scaling */
161 if(CallNtPowerInformation(SystemPowerCapabilities, 0, 0, &s, sizeof(s)) == STATUS_SUCCESS)
163 if(s.ProcessorMinThrottle != 100 || s.ProcessorMaxThrottle != 100)
165 s.ProcessorMinThrottle = 100;
166 s.ProcessorMaxThrottle = 100;
167 if(CallNtPowerInformation(SystemPowerCapabilities, &s, sizeof(s), 0, 0) != STATUS_SUCCESS)
168 puts("Can't disable dynamic CPU frequency scaling!");
171 else puts("Can't disable dynamic CPU frequency scaling!");
173 /* set priority */
174 if(!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS))
175 puts("SetPriorityClass() failed!");
177 /* lock process to one core */
178 if(!SetProcessAffinityMask(GetCurrentProcess(), 1))
179 puts("SetProcessAffinityMask() failed!");
181 #endif
183 /* calibrate */
184 perf_c = 0;
185 PERF_START
186 PERF_STOP
187 perf_c = cycles;
190 void perf_rest(void)
192 #if defined(PERF_UNIX)
193 (void)sleep(1);
194 #elif defined(PERF_WINDOWS)
195 (void)Sleep(1);
196 #endif