bench_blocksize.c
download raw
#define COPY_ITERS 10
#define ITERS 1000
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/eventfd.h>
#define SECOND 1000000000
#define MILLISECOND 1000000
#define MICROSECOND 1000
#define MEG (1024 * 1024)
#define HALFMEG (MEG >> 1)
#define MEG2 (MEG * 2)
#define MEG8 (MEG * 8)
static const uint64_t PHI = 0x9e3779b97f4a7c15;
static uint64_t rand_state;
static uint64_t rand_u64() {
rand_state += PHI;
uint64_t z = rand_state;
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
typedef struct {
struct timespec start, end;
} bench;
// can fit everything into a float in nanoseconds.
double diff(struct timespec start, struct timespec end)
{
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return (double)((1000000000ULL * (uint64_t)temp.tv_sec) + temp.tv_nsec);
}
void print_stat(double stat) {
if (stat >= SECOND) {
printf("%7.3f secs", stat / SECOND);
return;
}
if (stat >= MILLISECOND) {
printf("%7.3f msec", stat / MILLISECOND);
return;
}
if (stat >= MICROSECOND) {
printf("%7.3f usec", stat / MICROSECOND);
return;
}
printf("%7.3f nsec", stat);
}
void print_bench(char *name, bench b) {
double delta = diff(b.start, b.end);
printf("%-20s ", name);
print_stat(delta);
printf(" ( ");
print_stat(delta / ITERS);
printf(" per iteration )\n");
}
bench bench_bs512k_thr1_copy(int in, int out, char * buf) {
bench b;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.start);
for (int block = 0; block < 2048; block++) {
for (int index = 0; index < HALFMEG; ) {
ssize_t ret = read(in, &buf[index], HALFMEG - index);
if (ret == -1) {
fprintf(stderr, "Unexpected read error: %d", errno);
exit(1);
} else {
index += ret;
}
}
for (int index = 0; index < HALFMEG; ) {
ssize_t ret = write(out, &buf[index], HALFMEG - index);
if (ret == -1) {
fprintf(stderr, "Unexpected write error: %d", errno);
exit(1);
} else {
index += ret;
}
}
}
int ret = fsync(out);
if (ret == -1) {
fprintf(stderr, "Unexpected fsync error: %d", errno);
exit(3);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.end);
return b;
}
bench bench_bs1m_thr1_copy(int in, int out, char * buf) {
bench b;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.start);
for (int block = 0; block < 1024; block++) {
for (int index = 0; index < MEG; ) {
ssize_t ret = read(in, &buf[index], MEG - index);
if (ret == -1) {
fprintf(stderr, "Unexpected read error: %d", errno);
exit(1);
} else {
index += ret;
}
}
for (int index = 0; index < MEG; ) {
ssize_t ret = write(out, &buf[index], MEG - index);
if (ret == -1) {
fprintf(stderr, "Unexpected write error: %d", errno);
exit(1);
} else {
index += ret;
}
}
}
int ret = fsync(out);
if (ret == -1) {
fprintf(stderr, "Unexpected fsync error: %d", errno);
exit(3);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.end);
return b;
}
bench bench_bs2m_thr1_copy(int in, int out, char * buf) {
bench b;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.start);
for (int block = 0; block < 512; block++) {
for (int index = 0; index < MEG2; ) {
ssize_t ret = read(in, &buf[index], MEG2 - index);
if (ret == -1) {
fprintf(stderr, "Unexpected read error: %d", errno);
exit(1);
} else {
index += ret;
}
}
for (int index = 0; index < MEG; ) {
ssize_t ret = write(out, &buf[index], MEG2 - index);
if (ret == -1) {
fprintf(stderr, "Unexpected write error: %d", errno);
exit(1);
} else {
index += ret;
}
}
}
int ret = fsync(out);
if (ret == -1) {
fprintf(stderr, "Unexpected fsync error: %d", errno);
exit(3);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.end);
return b;
}
bench bench_bs8m_thr1_copy(int in, int out, char * buf) {
bench b;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.start);
for (int block = 0; block < 128; block++) {
for (int index = 0; index < MEG8; ) {
ssize_t ret = read(in, &buf[index], MEG8 - index);
if (ret == -1) {
fprintf(stderr, "Unexpected read error: %d", errno);
exit(1);
} else {
index += ret;
}
}
for (int index = 0; index < MEG8; ) {
ssize_t ret = write(out, &buf[index], MEG8 - index);
if (ret == -1) {
fprintf(stderr, "Unexpected write error: %d", errno);
exit(1);
} else {
index += ret;
}
}
}
int ret = fsync(out);
if (ret == -1) {
fprintf(stderr, "Unexpected fsync error: %d", errno);
exit(3);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &b.end);
return b;
}
static char buf[8 * MEG];
int main(int argc, char **argv) {
struct timespec t;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
int efd = eventfd(0, 0);
int in = open("random", O_RDWR);
if (in == -1) {
fprintf(stderr, "error opening random: %d", errno);
return 1;
}
int out = open(".", O_RDWR | O_TMPFILE);
if (out == -1) {
fprintf(stderr, "error opening out: %d", errno);
return 1;
}
memset(buf, 0, sizeof(buf));
if (argc < 2 || strchr(argv[1], '5')) {
print_bench("copy bs=512K thr=1", bench_bs512k_thr1_copy(in, out, &buf[0]));
int ret = lseek(in, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
ret = lseek(out, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
}
if (argc < 2 || strchr(argv[1], '1')) {
print_bench("copy bs=1M thr=1", bench_bs1m_thr1_copy(in, out, &buf[0]));
int ret = lseek(in, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
ret = lseek(out, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
}
if (argc < 2 || strchr(argv[1], '2')) {
print_bench("copy bs=2M thr=1", bench_bs2m_thr1_copy(in, out, &buf[0]));
int ret = lseek(in, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
ret = lseek(out, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
}
if (argc < 2 || strchr(argv[1], '8')) {
print_bench("copy bs=8M thr=1", bench_bs8m_thr1_copy(in, out, &buf[0]));
int ret = lseek(in, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
ret = lseek(out, 0, SEEK_SET);
if (ret == -1) {
fprintf(stderr, "Unexpected lseek error: %d", errno);
exit(8);
}
}
/* print_bench("copy bs=1M thr=8", bench_bs1m_thr8_copy(in, out, efd, &buf[0])); */
return 0;
}