OXYGENHUB
# fa53a2849de8 oxygen / vendor / crc-fast / .kiro / specs / checksum-benchmark-option / design.md
5.7 KiB · Markdown · last changed Strata: the cloud stores send through ureq, so every release target links 1 month ago renderedsource blame history raw
2cd40ea1 Andy McCall ↶ 1
# Design Document
2
3
## Overview
4
5
This design extends the existing `bin/checksum.rs` tool with benchmark functionality through a new `-b` flag. The benchmark mode will measure CRC performance using either user-provided data (files/strings) or randomly generated data, reporting throughput in GiB/s along with the acceleration target used.
6
7
The design maintains backward compatibility while adding a clean benchmark interface that leverages existing patterns from the `benches/benchmark.rs` implementation.
8
9
## Architecture
10
11
### Command Line Interface
12
13
The tool will extend the existing argument parsing to support:
14
- `-b`: Enable benchmark mode
15
- `--size <bytes>`: Specify data size for random generation (when no file/string provided)
16
- `--duration <seconds>`: Benchmark duration as floating-point seconds (default: 10.0)
17
- Existing `-a <algorithm>`: CRC algorithm (required in benchmark mode)
18
- Existing `-f <file>` or `-s <string>`: Optional data source for benchmarking
19
20
### Data Flow
21
22
```
23
User Input → Argument Parsing → Mode Detection → Benchmark Execution → Results Display
24
                                      ↓
25
                              [Normal Checksum Mode]
26
                                      ↓
27
                              [Existing Functionality]
28
```
29
30
In benchmark mode:
31
1. Parse and validate benchmark parameters
32
2. Determine data source (file, string, or generated)
33
3. For string/generated data: Load/generate test data once; For file data: use file path directly
34
4. Run benchmark loop for specified duration using appropriate checksum function
35
5. Calculate and display results
36
37
## Components and Interfaces
38
39
### Enhanced Config Structure
40
41
```rust
42
#[derive(Debug)]
43
struct Config {
44
    algorithm: String,
45
    file: Option<String>,
46
    string: Option<String>,
47
    format: OutputFormat,
48
    benchmark: Option<BenchmarkConfig>,
49
}
50
51
#[derive(Debug)]
52
struct BenchmarkConfig {
53
    size: Option<usize>,
54
    duration: f64,
55
}
56
```
57
58
### Benchmark Execution Module
59
60
```rust
61
enum BenchmarkData {
62
    InMemory(Vec<u8>),
63
    File(String),
64
}
65
66
struct BenchmarkRunner {
67
    algorithm: CrcAlgorithm,
68
    data: BenchmarkData,
69
    duration: f64,
70
}
71
72
impl BenchmarkRunner {
73
    fn new(algorithm: CrcAlgorithm, data: BenchmarkData, duration: f64) -> Self
74
    fn run(&self) -> BenchmarkResult
75
}
76
77
struct BenchmarkResult {
78
    iterations: u64,
79
    elapsed_seconds: f64,
80
    throughput_gibs: f64,
81
    time_per_iteration_nanos: f64,
82
    acceleration_target: String,
83
    data_size: u64,
84
}
85
```
86
87
### Data Generation
88
89
The benchmark will reuse the random data generation pattern from `benches/benchmark.rs`:
90
91
```rust
92
fn generate_random_data(size: usize) -> Vec<u8> {
93
    let mut rng = rand::rng();
94
    let mut buf = vec![0u8; size];
95
    rng.fill_bytes(&mut buf);
96
    buf
97
}
98
```
99
100
## Data Models
101
102
### Input Data Sources
103
104
1. **File Input**: Use `checksum_file()` function to benchmark the entire file I/O and checksum stack
105
2. **String Input**: Use string bytes directly with in-memory `checksum()` function
106
3. **Generated Data**: Create random data of specified size using `rand::RngCore::fill_bytes()` and use in-memory `checksum()` function
107
108
### Benchmark Metrics
109
110
- **Iterations**: Number of checksum calculations performed
111
- **Elapsed Time**: Actual benchmark duration in seconds
112
- **Throughput**: Calculated as `(data_size * iterations) / elapsed_time / (1024^3)` GiB/s
113
- **Acceleration Target**: Result from `crc_fast::get_calculator_target(algorithm)`
114
115
## Error Handling
116
117
### Validation Errors
118
119
- Invalid algorithm names (reuse existing validation)
120
- Invalid size parameters (non-positive values)
121
- Invalid duration parameters (non-positive values)
122
- File read errors (reuse existing error handling)
123
124
### Runtime Errors
125
126
- Memory allocation failures for large data sizes
127
- Timer precision issues (fallback to alternative timing methods)
128
129
### Error Messages
130
131
All errors will follow the existing pattern of displaying the error message followed by usage information.
132
133
## Testing Strategy
134
135
### Unit Tests
136
137
- Argument parsing validation for benchmark flags
138
- BenchmarkConfig creation and validation
139
- Data generation with various sizes
140
- Throughput calculation accuracy
141
142
### Integration Tests
143
144
- End-to-end benchmark execution with different algorithms
145
- File and string input handling in benchmark mode
146
- Error handling for invalid parameters
147
- Backward compatibility verification
148
149
### Performance Validation
150
151
- Verify benchmark results are reasonable (within expected ranges)
152
- Compare with existing `benches/benchmark.rs` results for consistency
153
- Test with various data sizes to ensure linear scaling
154
155
## Implementation Notes
156
157
### Timing Mechanism
158
159
Use `std::time::Instant` for high-precision timing, with different approaches for different data sources:
160
161
```rust
162
let start = std::time::Instant::now();
163
let mut iterations = 0u64;
164
165
while start.elapsed().as_secs_f64() < duration {
166
    match &self.data {
167
        BenchmarkData::InMemory(data) => {
168
            std::hint::black_box(checksum(algorithm, data));
169
        }
170
        BenchmarkData::File(filename) => {
171
            std::hint::black_box(checksum_file(algorithm, filename, None).unwrap());
172
        }
173
    }
174
    iterations += 1;
175
}
176
177
let elapsed = start.elapsed().as_secs_f64();
178
```
179
180
### Memory Considerations
181
182
- Pre-allocate test data once before benchmark loop
183
- Use `std::hint::black_box()` to prevent compiler optimizations
184
- Consider memory alignment for optimal performance (optional enhancement)
185
186
### Output Format
187
188
```
189
Algorithm: CRC-32/ISCSI
190
Acceleration Target: aarch64-neon-sha3
191
Data Size: 1,048,576 bytes (1.0 MiB)
192
Duration: 10.00 seconds
193
Iterations: 12,345
194
Throughput: 45.67 GiB/s
195
Time per iteration: 810.2 μs
196
```
197
198
### Default Values
199
200
- **Size**: 1,048,576 bytes (1 MiB)
201
- **Duration**: 10.0 seconds
202
- **Algorithm**: Must be specified via `-a` flag (no default)