]>
Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
7fe2f639 DB |
2 | /* cpufreq-bench CPUFreq microbenchmark |
3 | * | |
4 | * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> | |
7fe2f639 DB |
5 | */ |
6 | ||
7 | #include <stdio.h> | |
8 | #include <unistd.h> | |
9 | #include <math.h> | |
10 | ||
11 | #include "config.h" | |
12 | #include "system.h" | |
13 | #include "benchmark.h" | |
14 | ||
15 | /* Print out progress if we log into a file */ | |
16 | #define show_progress(total_time, progress_time) \ | |
17 | if (config->output != stdout) { \ | |
18 | fprintf(stdout, "Progress: %02lu %%\r", \ | |
19 | (progress_time * 100) / total_time); \ | |
20 | fflush(stdout); \ | |
21 | } | |
22 | ||
23 | /** | |
24 | * compute how many rounds of calculation we should do | |
25 | * to get the given load time | |
26 | * | |
02af3cb5 | 27 | * @param load aimed load time in µs |
7fe2f639 DB |
28 | * |
29 | * @retval rounds of calculation | |
30 | **/ | |
31 | ||
32 | unsigned int calculate_timespace(long load, struct config *config) | |
33 | { | |
34 | int i; | |
35 | long long now, then; | |
36 | unsigned int estimated = GAUGECOUNT; | |
37 | unsigned int rounds = 0; | |
38 | unsigned int timed = 0; | |
39 | ||
40 | if (config->verbose) | |
41 | printf("calibrating load of %lius, please wait...\n", load); | |
42 | ||
43 | /* get the initial calculation time for a specific number of rounds */ | |
44 | now = get_time(); | |
45 | ROUNDS(estimated); | |
46 | then = get_time(); | |
47 | ||
48 | timed = (unsigned int)(then - now); | |
49 | ||
50 | /* approximation of the wanted load time by comparing with the | |
02af3cb5 DB |
51 | * initial calculation time */ |
52 | for (i = 0; i < 4; i++) { | |
7fe2f639 DB |
53 | rounds = (unsigned int)(load * estimated / timed); |
54 | dprintf("calibrating with %u rounds\n", rounds); | |
55 | now = get_time(); | |
56 | ROUNDS(rounds); | |
57 | then = get_time(); | |
58 | ||
59 | timed = (unsigned int)(then - now); | |
60 | estimated = rounds; | |
61 | } | |
62 | if (config->verbose) | |
63 | printf("calibration done\n"); | |
64 | ||
65 | return estimated; | |
66 | } | |
67 | ||
68 | /** | |
69 | * benchmark | |
70 | * generates a specific sleep an load time with the performance | |
71 | * governor and compares the used time for same calculations done | |
72 | * with the configured powersave governor | |
73 | * | |
74 | * @param config config values for the benchmark | |
75 | * | |
76 | **/ | |
77 | ||
78 | void start_benchmark(struct config *config) | |
79 | { | |
80 | unsigned int _round, cycle; | |
81 | long long now, then; | |
82 | long sleep_time = 0, load_time = 0; | |
83 | long performance_time = 0, powersave_time = 0; | |
84 | unsigned int calculations; | |
85 | unsigned long total_time = 0, progress_time = 0; | |
86 | ||
87 | sleep_time = config->sleep; | |
88 | load_time = config->load; | |
89 | ||
90 | /* For the progress bar */ | |
02af3cb5 | 91 | for (_round = 1; _round <= config->rounds; _round++) |
7fe2f639 DB |
92 | total_time += _round * (config->sleep + config->load); |
93 | total_time *= 2; /* powersave and performance cycles */ | |
94 | ||
02af3cb5 | 95 | for (_round = 0; _round < config->rounds; _round++) { |
7fe2f639 DB |
96 | performance_time = 0LL; |
97 | powersave_time = 0LL; | |
98 | ||
99 | show_progress(total_time, progress_time); | |
100 | ||
101 | /* set the cpufreq governor to "performance" which disables | |
102 | * P-State switching. */ | |
103 | if (set_cpufreq_governor("performance", config->cpu) != 0) | |
104 | return; | |
105 | ||
106 | /* calibrate the calculation time. the resulting calculation | |
107 | * _rounds should produce a load which matches the configured | |
108 | * load time */ | |
109 | calculations = calculate_timespace(load_time, config); | |
110 | ||
111 | if (config->verbose) | |
112 | printf("_round %i: doing %u cycles with %u calculations" | |
113 | " for %lius\n", _round + 1, config->cycles, | |
114 | calculations, load_time); | |
115 | ||
116 | fprintf(config->output, "%u %li %li ", | |
117 | _round, load_time, sleep_time); | |
118 | ||
02af3cb5 | 119 | if (config->verbose) |
fe7656a8 | 120 | printf("average: %lius, rps:%li\n", |
02af3cb5 DB |
121 | load_time / calculations, |
122 | 1000000 * calculations / load_time); | |
7fe2f639 DB |
123 | |
124 | /* do some sleep/load cycles with the performance governor */ | |
125 | for (cycle = 0; cycle < config->cycles; cycle++) { | |
126 | now = get_time(); | |
127 | usleep(sleep_time); | |
128 | ROUNDS(calculations); | |
129 | then = get_time(); | |
130 | performance_time += then - now - sleep_time; | |
131 | if (config->verbose) | |
02af3cb5 DB |
132 | printf("performance cycle took %lius, " |
133 | "sleep: %lius, " | |
134 | "load: %lius, rounds: %u\n", | |
135 | (long)(then - now), sleep_time, | |
136 | load_time, calculations); | |
7fe2f639 | 137 | } |
02af3cb5 DB |
138 | fprintf(config->output, "%li ", |
139 | performance_time / config->cycles); | |
7fe2f639 DB |
140 | |
141 | progress_time += sleep_time + load_time; | |
142 | show_progress(total_time, progress_time); | |
143 | ||
144 | /* set the powersave governor which activates P-State switching | |
145 | * again */ | |
146 | if (set_cpufreq_governor(config->governor, config->cpu) != 0) | |
147 | return; | |
148 | ||
02af3cb5 DB |
149 | /* again, do some sleep/load cycles with the |
150 | * powersave governor */ | |
7fe2f639 DB |
151 | for (cycle = 0; cycle < config->cycles; cycle++) { |
152 | now = get_time(); | |
153 | usleep(sleep_time); | |
154 | ROUNDS(calculations); | |
155 | then = get_time(); | |
156 | powersave_time += then - now - sleep_time; | |
157 | if (config->verbose) | |
02af3cb5 DB |
158 | printf("powersave cycle took %lius, " |
159 | "sleep: %lius, " | |
160 | "load: %lius, rounds: %u\n", | |
161 | (long)(then - now), sleep_time, | |
162 | load_time, calculations); | |
7fe2f639 DB |
163 | } |
164 | ||
165 | progress_time += sleep_time + load_time; | |
166 | ||
fe7656a8 | 167 | /* compare the average sleep/load cycles */ |
02af3cb5 DB |
168 | fprintf(config->output, "%li ", |
169 | powersave_time / config->cycles); | |
170 | fprintf(config->output, "%.3f\n", | |
171 | performance_time * 100.0 / powersave_time); | |
7fe2f639 DB |
172 | fflush(config->output); |
173 | ||
174 | if (config->verbose) | |
02af3cb5 DB |
175 | printf("performance is at %.2f%%\n", |
176 | performance_time * 100.0 / powersave_time); | |
7fe2f639 DB |
177 | |
178 | sleep_time += config->sleep_step; | |
179 | load_time += config->load_step; | |
180 | } | |
181 | } |