brewery
notashelf /
dc9f159470cb818cdddff1cd0dd6ee083be50eed

chroma

public

Lightweight wallpaper daemon for Wayland

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/chroma.git
benchmarks/bench.cC332 lines9.9 KB
1
#include "test_common.h"
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <sys/time.h>
6
7
typedef struct {
8
    double time_ms;
9
    double pixels_per_sec;
10
    double megabytes_per_sec;
11
    size_t input_bytes;
12
    size_t output_bytes;
13
} BenchResult;
14
15
static double get_time_us(void) {
16
    struct timeval tv;
17
    gettimeofday(&tv, NULL);
18
    return tv.tv_sec * 1000000.0 + tv.tv_usec;
19
}
20
21
static void calculate_bench_metrics(const char *name, int iterations, BenchResult *r) {
22
    if (strstr(name, "create_uniform") != NULL) {
23
        r->input_bytes = 0;
24
        r->output_bytes = 16 * 16 * 4;
25
    } else if (strstr(name, "create_gradient_256") != NULL) {
26
        r->input_bytes = 0;
27
        r->output_bytes = 256 * 256 * 4;
28
    } else if (strstr(name, "create_noise_1024") != NULL) {
29
        r->input_bytes = 0;
30
        r->output_bytes = 1024 * 1024 * 4;
31
    } else if (strstr(name, "downsample_uniform_16x16") != NULL) {
32
        r->input_bytes = 16 * 16 * 4;
33
        r->output_bytes = 8 * 8 * 4;
34
    } else if (strstr(name, "downsample_gradient_64x64") != NULL) {
35
        r->input_bytes = 64 * 64 * 4;
36
        r->output_bytes = 32 * 32 * 4;
37
    } else if (strstr(name, "downsample_gradient_256x256") != NULL) {
38
        r->input_bytes = 256 * 256 * 4;
39
        r->output_bytes = 128 * 128 * 4;
40
    } else if (strstr(name, "downsample_gradient_1024x1024") != NULL) {
41
        r->input_bytes = 1024 * 1024 * 4;
42
        r->output_bytes = 512 * 512 * 4;
43
    } else if (strstr(name, "downsample_noise_512x512") != NULL) {
44
        r->input_bytes = 512 * 512 * 4;
45
        r->output_bytes = 128 * 128 * 4;
46
    } else if (strstr(name, "downsample_noise_1024x1024") != NULL) {
47
        r->input_bytes = 1024 * 1024 * 4;
48
        r->output_bytes = 256 * 256 * 4;
49
    } else if (strstr(name, "downsample_noise_1920x1080") != NULL) {
50
        r->input_bytes = 1920 * 1080 * 4;
51
        r->output_bytes = 960 * 540 * 4;
52
    } else if (strstr(name, "downsample_noise_3840x2160") != NULL) {
53
        r->input_bytes = 3840 * 2160 * 4;
54
        r->output_bytes = 1920 * 1080 * 4;
55
    } else if (strstr(name, "downsample_noise_4096x4096") != NULL) {
56
        r->input_bytes = 4096 * 4096 * 4;
57
        r->output_bytes = 1024 * 1024 * 4;
58
    } else if (strstr(name, "downsample_checkerboard_100x100") != NULL) {
59
        r->input_bytes = 100 * 100 * 4;
60
        r->output_bytes = 50 * 50 * 4;
61
    } else if (strstr(name, "downsample_checkerboard_256x256") != NULL) {
62
        r->input_bytes = 256 * 256 * 4;
63
        r->output_bytes = 128 * 128 * 4;
64
    } else {
65
        r->input_bytes = 0;
66
        r->output_bytes = 0;
67
    }
68
    r->input_bytes *= (size_t)iterations;
69
    r->output_bytes *= (size_t)iterations;
70
}
71
72
static void run_bench(double (*fn)(void), int iterations, double *elapsed_ms) {
73
    double start = get_time_us();
74
    for (int i = 0; i < iterations; i++) {
75
        fn();
76
    }
77
    *elapsed_ms = (get_time_us() - start) / 1000.0;
78
}
79
80
static double bench_create_uniform_16x16(void) {
81
    for (int i = 0; i < 5000; i++) {
82
        uint8_t *img = create_uniform_image(16, 16, 128, 128, 128);
83
        free(img);
84
    }
85
    return 0;
86
}
87
88
static double bench_create_gradient_256x256(void) {
89
    for (int i = 0; i < 500; i++) {
90
        uint8_t *img = create_gradient_image(256, 256);
91
        free(img);
92
    }
93
    return 0;
94
}
95
96
static double bench_create_noise_1024x1024(void) {
97
    for (int i = 0; i < 50; i++) {
98
        uint8_t *img = create_noise_image(1024, 1024, 42);
99
        free(img);
100
    }
101
    return 0;
102
}
103
104
static double bench_downsample_uniform_16x16(void) {
105
    uint8_t *src = create_uniform_image(16, 16, 128, 128, 128);
106
    int dw, dh;
107
108
    for (int i = 0; i < 2000; i++) {
109
        uint8_t *dst = downsample_image(src, 16, 16, 4, &dw, &dh, 0.5f);
110
        free(dst);
111
    }
112
113
    free(src);
114
    return 0;
115
}
116
117
static double bench_downsample_gradient_64x64(void) {
118
    uint8_t *src = create_gradient_image(64, 64);
119
    int dw, dh;
120
121
    for (int i = 0; i < 500; i++) {
122
        uint8_t *dst = downsample_image(src, 64, 64, 4, &dw, &dh, 0.5f);
123
        free(dst);
124
    }
125
126
    free(src);
127
    return 0;
128
}
129
130
static double bench_downsample_gradient_256x256(void) {
131
    uint8_t *src = create_gradient_image(256, 256);
132
    int dw, dh;
133
134
    for (int i = 0; i < 200; i++) {
135
        uint8_t *dst = downsample_image(src, 256, 256, 4, &dw, &dh, 0.5f);
136
        free(dst);
137
    }
138
139
    free(src);
140
    return 0;
141
}
142
143
static double bench_downsample_gradient_1024x1024(void) {
144
    uint8_t *src = create_gradient_image(1024, 1024);
145
    int dw, dh;
146
147
    for (int i = 0; i < 20; i++) {
148
        uint8_t *dst = downsample_image(src, 1024, 1024, 4, &dw, &dh, 0.5f);
149
        free(dst);
150
    }
151
152
    free(src);
153
    return 0;
154
}
155
156
static double bench_downsample_noise_512x512(void) {
157
    uint8_t *src = create_noise_image(512, 512, 42);
158
    int dw, dh;
159
160
    for (int i = 0; i < 50; i++) {
161
        uint8_t *dst = downsample_image(src, 512, 512, 4, &dw, &dh, 0.25f);
162
        free(dst);
163
    }
164
165
    free(src);
166
    return 0;
167
}
168
169
static double bench_downsample_noise_1024x1024(void) {
170
    uint8_t *src = create_noise_image(1024, 1024, 123);
171
    int dw, dh;
172
173
    for (int i = 0; i < 15; i++) {
174
        uint8_t *dst = downsample_image(src, 1024, 1024, 4, &dw, &dh, 0.25f);
175
        free(dst);
176
    }
177
178
    free(src);
179
    return 0;
180
}
181
182
static double bench_downsample_noise_1920x1080(void) {
183
    uint8_t *src = create_noise_image(1920, 1080, 456);
184
    int dw, dh;
185
186
    for (int i = 0; i < 5; i++) {
187
        uint8_t *dst = downsample_image(src, 1920, 1080, 4, &dw, &dh, 0.5f);
188
        free(dst);
189
    }
190
191
    free(src);
192
    return 0;
193
}
194
195
static double bench_downsample_noise_3840x2160(void) {
196
    uint8_t *src = create_noise_image(3840, 2160, 789);
197
    int dw, dh;
198
199
    for (int i = 0; i < 2; i++) {
200
        uint8_t *dst = downsample_image(src, 3840, 2160, 4, &dw, &dh, 0.5f);
201
        free(dst);
202
    }
203
204
    free(src);
205
    return 0;
206
}
207
208
static double bench_downsample_noise_4096x4096(void) {
209
    uint8_t *src = create_noise_image(4096, 4096, 456);
210
    int dw, dh;
211
212
    for (int i = 0; i < 2; i++) {
213
        uint8_t *dst = downsample_image(src, 4096, 4096, 4, &dw, &dh, 0.25f);
214
        free(dst);
215
    }
216
217
    free(src);
218
    return 0;
219
}
220
221
static double bench_downsample_checkerboard_100x100(void) {
222
    uint8_t *src = create_checkerboard(100, 100, 10);
223
    int dw, dh;
224
225
    for (int i = 0; i < 200; i++) {
226
        uint8_t *dst = downsample_image(src, 100, 100, 4, &dw, &dh, 0.5f);
227
        free(dst);
228
    }
229
230
    free(src);
231
    return 0;
232
}
233
234
static double bench_downsample_checkerboard_256x256(void) {
235
    uint8_t *src = create_checkerboard(256, 256, 16);
236
    int dw, dh;
237
238
    for (int i = 0; i < 100; i++) {
239
        uint8_t *dst = downsample_image(src, 256, 256, 4, &dw, &dh, 0.5f);
240
        free(dst);
241
    }
242
243
    free(src);
244
    return 0;
245
}
246
247
typedef struct {
248
    const char *name;
249
    double (*fn)(void);
250
} BenchDef;
251
252
static BenchDef benchmarks[] = {
253
    {"create_uniform_16x16", bench_create_uniform_16x16},
254
    {"create_gradient_256x256", bench_create_gradient_256x256},
255
    {"create_noise_1024x1024", bench_create_noise_1024x1024},
256
    {"downsample_uniform_16x16_0.5x", bench_downsample_uniform_16x16},
257
    {"downsample_gradient_64x64_0.5x", bench_downsample_gradient_64x64},
258
    {"downsample_gradient_256x256_0.5x", bench_downsample_gradient_256x256},
259
    {"downsample_gradient_1024x1024_0.5x", bench_downsample_gradient_1024x1024},
260
    {"downsample_noise_512x512_0.25x", bench_downsample_noise_512x512},
261
    {"downsample_noise_1024x1024_0.25x", bench_downsample_noise_1024x1024},
262
    {"downsample_noise_1920x1080_0.5x", bench_downsample_noise_1920x1080},
263
    {"downsample_noise_3840x2160_0.5x", bench_downsample_noise_3840x2160},
264
    {"downsample_noise_4096x4096_0.25x", bench_downsample_noise_4096x4096},
265
    {"downsample_checkerboard_100x100_0.5x", bench_downsample_checkerboard_100x100},
266
    {"downsample_checkerboard_256x256_0.5x", bench_downsample_checkerboard_256x256},
267
};
268
269
static int benchmark_iterations[] = {
270
    5000, 500, 50, 2000, 500, 200, 20, 50, 15, 5, 2, 2, 200, 100
271
};
272
273
int main(int argc, char **argv) {
274
    int csv_output = 0;
275
276
    for (int i = 1; i < argc; i++) {
277
        if (strcmp(argv[i], "--csv") == 0) {
278
            csv_output = 1;
279
        }
280
    }
281
282
    if (csv_output) {
283
        printf("name,time_ms,pixels_per_sec,megabytes_per_sec,iterations\n");
284
    } else {
285
        printf("Chroma Performance Benchmarks\n");
286
        printf("=============================\n\n");
287
        printf("  %-42s %16s %22s %19s\n", "Benchmark", "Time (ms)", "Pixels/sec", "MB/sec");
288
        printf("  %-42s %16s %22s %19s\n", "-----------------------------------------", "--------------", "-----------------", "--------------");
289
    }
290
291
    int num_benchmarks = sizeof(benchmarks) / sizeof(benchmarks[0]);
292
    int max_name_len = 0;
293
    for (int i = 0; i < num_benchmarks; i++) {
294
        int len = strlen(benchmarks[i].name);
295
        if (len > max_name_len) max_name_len = len;
296
    }
297
298
    for (int i = 0; i < num_benchmarks; i++) {
299
        BenchResult result = {0};
300
        calculate_bench_metrics(benchmarks[i].name, benchmark_iterations[i], &result);
301
302
        double elapsed_ms;
303
        run_bench(benchmarks[i].fn, benchmark_iterations[i], &elapsed_ms);
304
305
        size_t total_pixels = result.input_bytes > 0 ? result.input_bytes / 4 : 0;
306
        result.time_ms = elapsed_ms;
307
        if (total_pixels > 0 && elapsed_ms > 0) {
308
            result.pixels_per_sec = total_pixels / (elapsed_ms / 1000.0);
309
        }
310
        double total_mb = (result.input_bytes + result.output_bytes) / (1024.0 * 1024.0);
311
        if (total_mb > 0 && elapsed_ms > 0) {
312
            result.megabytes_per_sec = total_mb / (elapsed_ms / 1000.0);
313
        }
314
315
        if (csv_output) {
316
            printf("%s,%.3f,%.0f,%.2f,%d\n",
317
                   benchmarks[i].name, result.time_ms, result.pixels_per_sec,
318
                   result.megabytes_per_sec, benchmark_iterations[i]);
319
        } else {
320
            printf("  %-42s %16.3f %22.0f %19.2f\n",
321
                   benchmarks[i].name, result.time_ms,
322
                   result.pixels_per_sec, result.megabytes_per_sec);
323
        }
324
    }
325
326
    if (!csv_output) {
327
        printf("\n");
328
    }
329
330
    (void)argc;
331
    return 0;
332
}