-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbench.c
More file actions
141 lines (118 loc) · 4.37 KB
/
bench.c
File metadata and controls
141 lines (118 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* libdimfold benchmark — measures throughput and compression ratio
* across different data sizes and configurations.
*
* Build: make bench
* Run: ./bench
*/
#define _POSIX_C_SOURCE 199309L
#include "dimfold.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
static double wallclock(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (double)ts.tv_sec + (double)ts.tv_nsec * 1e-9;
}
static void bench_size(int n, int iterations)
{
double *data = (double *)malloc((size_t)n * sizeof(double));
if (!data) return;
srand(12345);
for (int i = 0; i < n; i++)
data[i] = ((double)rand() / RAND_MAX - 0.5) * 2.0;
/* Warm up */
df_result_t r = df_compress(data, (size_t)n, NULL);
df_result_free(&r);
/* Compress benchmark */
double t0 = wallclock();
for (int it = 0; it < iterations; it++) {
r = df_compress(data, (size_t)n, NULL);
df_result_free(&r);
}
double compress_time = (wallclock() - t0) / iterations;
/* Final compress for stats */
r = df_compress(data, (size_t)n, NULL);
/* Decompress benchmark */
double *restored = (double *)malloc((size_t)n * sizeof(double));
t0 = wallclock();
for (int it = 0; it < iterations; it++)
df_decompress(&r, restored, (size_t)n);
double decompress_time = (wallclock() - t0) / iterations;
double orig_norm = df_norm(data, (size_t)n);
double rest_norm = df_norm(restored, (size_t)n);
double norm_err = (orig_norm > 1e-15) ? fabs(orig_norm - rest_norm) / orig_norm : 0.0;
printf(" %8d doubles | %7zu -> %4zu bytes | %7.0fx | "
"comp %7.1f us | decomp %7.1f us | "
"%6.0f MB/s | norm_err %.2e\n",
n, n * sizeof(double), r.packed_len, r.ratio,
compress_time * 1e6, decompress_time * 1e6,
((double)(n * sizeof(double)) / compress_time) / (1024.0 * 1024.0),
norm_err);
df_result_free(&r);
free(restored);
free(data);
}
int main(void)
{
printf("libdimfold v%s benchmark\n\n", df_version());
int sizes[] = {8, 16, 64, 256, 1024, 4096, 8192, 32768, 131072};
int n_sizes = sizeof(sizes) / sizeof(sizes[0]);
printf("── Random data, default opts (16D fold, 16-bit quant, Fermat p=167) ──\n");
for (int i = 0; i < n_sizes; i++) {
int iters = (sizes[i] <= 1024) ? 10000 : (sizes[i] <= 8192) ? 1000 : 100;
bench_size(sizes[i], iters);
}
printf("\n── Comparison: with vs without Fermat bridge (n=1024) ──\n");
{
double *data = (double *)malloc(1024 * sizeof(double));
srand(99);
for (int i = 0; i < 1024; i++)
data[i] = ((double)rand() / RAND_MAX - 0.5) * 2.0;
df_opts_t o_on = df_defaults();
df_opts_t o_off = df_defaults();
o_off.enable_fermat = 0;
double t0 = wallclock();
for (int it = 0; it < 10000; it++) {
df_result_t r = df_compress(data, 1024, &o_on);
df_result_free(&r);
}
double t_on = (wallclock() - t0) / 10000;
t0 = wallclock();
for (int it = 0; it < 10000; it++) {
df_result_t r = df_compress(data, 1024, &o_off);
df_result_free(&r);
}
double t_off = (wallclock() - t0) / 10000;
printf(" Fermat ON: %.1f us/op\n", t_on * 1e6);
printf(" Fermat OFF: %.1f us/op\n", t_off * 1e6);
printf(" Overhead: %.1f%%\n", ((t_on - t_off) / t_off) * 100.0);
free(data);
}
printf("\n── Quantization precision comparison (n=4096) ──\n");
{
double *data = (double *)malloc(4096 * sizeof(double));
srand(77);
for (int i = 0; i < 4096; i++)
data[i] = sin((double)i * 0.01) * ((double)rand() / RAND_MAX);
int bits[] = {8, 16, 32};
for (int b = 0; b < 3; b++) {
df_opts_t o = df_defaults();
o.quant_bits = bits[b];
df_result_t r = df_compress(data, 4096, &o);
double *rest = (double *)malloc(4096 * sizeof(double));
df_decompress(&r, rest, 4096);
double err = df_relative_error(data, rest, 4096);
printf(" %2d-bit: %4zu bytes, ratio %6.0fx, error %.2e\n",
bits[b], r.packed_len, r.ratio, err);
df_result_free(&r);
free(rest);
}
free(data);
}
return 0;
}