-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathseq_read_bench.cpp
More file actions
145 lines (118 loc) · 4.4 KB
/
seq_read_bench.cpp
File metadata and controls
145 lines (118 loc) · 4.4 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
142
143
144
145
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <string>
#include <format>
#include <fcntl.h> // For posix open flags
#include <unistd.h> // For posix read
#define FILE_SIZE (1024 * 1024 * 64) // 64 MiB
#define SMALL_CHUNK 100
#define MEDIUM_CHUNK 1024
#define INCREMENTAL 8192
#define INCREMENTAL_START 8192
#define LARGEST_CHUNK (256 * 1024)
struct BenchmarkResult {
int chunk_size;
int run_number;
double read_time_ms;
double throughput_mbps;
};
void write_result(int data_fd, const struct BenchmarkResult& result) {
std::string results_str = std::format("{},{},{:.3f},{:.3f}\n",
result.chunk_size,
result.run_number,
result.read_time_ms,
result.throughput_mbps
);
ssize_t written = write(data_fd, results_str.data(), results_str.size());
if (written != results_str.size()) {
std::cerr << "Error writing result to file\n";
std::exit(EXIT_FAILURE);
}
}
void benchmark_chunk_size(int chunk_size, int data_fd) {
void* buffer = std::malloc(chunk_size);
if (buffer == NULL) {
std::cerr << "Could not allocate chunk buffer!\n";
exit(1);
}
for (int run = 0; run < 30; run++) {
// Open test file
int test_fd = open("test_file.bin", O_RDONLY);
if (test_fd == -1) {
std::cerr << "Could not open test file\n";
std::free(buffer);
std::exit(EXIT_FAILURE);
}
std::cout << "File descriptor is %d\n" << test_fd;
auto start = std::chrono::high_resolution_clock::now();
// Read entire file in chunks
int total_read = 0;
ssize_t bytes_read;
while (total_read < FILE_SIZE) {
int to_read = (FILE_SIZE - total_read > chunk_size) ?
chunk_size : (FILE_SIZE - total_read);
bytes_read = read(test_fd, buffer, to_read);
if (bytes_read <= 0) break;
total_read += bytes_read;
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> start_stop_diff = end - start;
// Close test file
if (close(test_fd) == -1) {
std::cerr << "Error closing test file\n";
std::exit(EXIT_FAILURE);
}
std::cout << "Read " << total_read << "bytes\n";
if (total_read != FILE_SIZE) {
std::cerr << "Could not read entire file!\n";
std::free(buffer);
std::exit(EXIT_FAILURE);
}
// Calculate metrics
double read_time_ms = start_stop_diff.count() * 1000.0;
double throughput_mbps = (FILE_SIZE / (1024.0 * 1024.0)) / start_stop_diff.count();
// Write result
struct BenchmarkResult result = {chunk_size, run + 1, read_time_ms, throughput_mbps};
write_result(data_fd, result);
}
std::free(buffer);
}
int main() {
// Open data output file
int data_fd = open("benchmark_results.csv", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (data_fd == -1) {
perror("Could not open output file");
return 1;
}
// Write CSV header
std::string header = "chunk_size,run_number,read_time_ms,throughput_mbps\n";
ssize_t header_written = write(data_fd, header.data(), header.size());
if (header_written != header.size()) {
fprintf(stderr, "Error writing CSV header\n");
close(data_fd);
return 1;
}
std::cout << "Starting sequential read benchmark...\n";
// Benchmark small reads (100 bytes)
std::cout << "Testing small reads (100 bytes)\n";
benchmark_chunk_size(SMALL_CHUNK, data_fd);
// Benchmark medium reads (1K)
std::cout << "Testing medium reads (1K)\n";
benchmark_chunk_size(MEDIUM_CHUNK, data_fd);
// Benchmark large reads (64K)
std::cout << "Testing incremental reads of 8KiB starting from 8KiB up to 256KiB\n";
for (int incremental_chunk_size = INCREMENTAL_START;
incremental_chunk_size <= LARGEST_CHUNK;
incremental_chunk_size +=INCREMENTAL)
{
benchmark_chunk_size(incremental_chunk_size, data_fd);
}
// Close output file
if (close(data_fd) == -1) {
std::cout << "Error closing output file\n";
return 1;
}
std::cout << "Benchmark completed. Results saved to benchmark_results.csv\n";
return 0;
}