Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <hdr_histogram.h>
#define KB 1024UL
#define MB KB * KB
#define GB MB * KB
#define BLOCKSIZE 4096
#define EXIT(s) {\
perror((s));\
exit(EXIT_FAILURE); }
void
get_file_of_size (char *filename, off_t length) {
int handle = open (filename, O_RDWR | O_CREAT | O_EXCL, 0666);
if (handle == -1) {
EXIT ("open failed");
}
if (chmod (filename, 0666)) {
EXIT ("chmod failed");
}
close (handle);
if (truncate(filename, length)) {
EXIT ("truncate failed");
}
}
unsigned char *
get_buffer(size_t size) {
void *data;
if(posix_memalign(&data, BLOCKSIZE, size)) {
EXIT ("posix mem align");
}
for (int i=0;i<size;i++) {
((unsigned char *) data) [i] = (unsigned char) i % 256;
}
return data;
}
double
get_op_time (struct timeval start, struct timeval end) {
double opTime = (end.tv_sec - start.tv_sec) * 1000.0;
opTime += (end.tv_usec - start.tv_usec) / 1000.0;
return opTime;
}
int
safe_write (int fd, unsigned char *data, int length) {
int sent = 0;
do {
int n = write (fd, data + sent, length - sent);
if(n <= 0)
EXIT ("Write failed.");
sent += n;
} while(sent < length);
return length;
}
void
do_file_write (char *filename, size_t write_size, uint64_t total, bool flush, bool dohistogram) {
struct hdr_histogram* histogram;
struct timeval start, end, opstart, opend;
gettimeofday(&start, NULL);
hdr_init(1,
INT64_C(3600000000),
3,
&histogram);
int32_t iterations = total / write_size;
void *data = get_buffer(write_size);
printf ("file_write flush=%s doing %d iterations of %lu size for %" PRId64 " total\n", flush ? "true" : "false", iterations, write_size, total);
int flags = O_RDWR | O_APPEND;
#ifdef __linux__
if (!flush) flags = flags | O_DIRECT;
#endif
int handle = open (filename, flags , 0666);
if (handle == -1) {
perror ("open failed");
}
#ifdef __OSX__
fcntl(fd, F_NOCACHE, 1)
#endif
for (uint64_t i=0;i<total;i+=write_size) {
gettimeofday (&opstart, NULL);
safe_write (handle, data, write_size);
if(flush && fsync (handle)) {
EXIT ("fsync failed.");
}
gettimeofday (&opend, NULL);
double optime = get_op_time (opstart, opend);
hdr_record_value (histogram, optime);
}
gettimeofday(&end, NULL);
double elapsedTime = get_op_time(start, end);
printf ("Total time %f\n", elapsedTime);
if(dohistogram) {
hdr_percentiles_print(histogram,
stdout,
5,
1.0,
CLASSIC);
}
free (data);
free (histogram);
}
void
do_mm_write(char *filename, size_t write_size, uint64_t total, bool flush, bool dohistogram) {
struct hdr_histogram* histogram;
struct timeval start, end, opstart, opend;
gettimeofday(&start, NULL);
hdr_init(1,
INT64_C(3600000000),
3,
&histogram);
int32_t iterations = total / write_size;
printf ("mmap_write flush=%s doing %d iterations of %lu size for %" PRId64 " total\n", flush ? "true" : "false", iterations, write_size, total);
int flags = O_RDWR;
int handle = open (filename, flags , 0666);
if (handle == -1) {
EXIT ("open failed");
}
uint8_t *mem = mmap (0, total, PROT_WRITE | PROT_WRITE, MAP_SHARED, handle, 0);
if (mem == MAP_FAILED)
EXIT ("mmap failed");
uint8_t *data = get_buffer(write_size);
uint8_t *current = mem;
uint8_t *last = mem + total;
while(current < last) {
gettimeofday (&opstart, NULL);
memcpy(current, data, write_size);
if (flush) {
if(msync(current, write_size, MS_SYNC) == -1) {
EXIT("msync");
}
}
current += write_size;
gettimeofday (&opend, NULL);
double optime = get_op_time (opstart, opend);
hdr_record_value (histogram, optime);
}
gettimeofday(&end, NULL);
double elapsedTime = get_op_time(start, end);
printf ("Total time %f\n", elapsedTime);
if(dohistogram) {
hdr_percentiles_print(histogram,
stdout,
5,
1.0,
CLASSIC);
}
if(munmap (mem, total) == -1) {
EXIT ("munmap");
}
free (data);
free (histogram);
}
int
main (int argc, char **argv) {
char *filename = "shitbird.bin";
bool dohistogram = false;
int filesize = 5;
get_file_of_size (filename, filesize * GB);
do_mm_write (filename, 4096, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096 * 2, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096 * 4, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096 * 8, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096 * 16, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096 * 32, filesize * GB, false, dohistogram);
do_mm_write (filename, 4096, filesize * GB, true, dohistogram);
do_mm_write (filename, 4096 * 2, filesize * GB, true, dohistogram);
do_mm_write (filename, 4096 * 4, filesize * GB, true, dohistogram);
do_mm_write (filename, 4096 * 8, filesize * GB, true, dohistogram);
do_mm_write (filename, 4096 * 16, filesize * GB, true, dohistogram);
do_mm_write (filename, 4096 * 32, filesize * GB, true, dohistogram);
do_file_write (filename, 4096, filesize * GB, true, dohistogram);
do_file_write (filename, 4096 * 2, filesize * GB, true, dohistogram);
do_file_write (filename, 4096 * 4, filesize * GB, true, dohistogram);
do_file_write (filename, 4096 * 8, filesize * GB, true, dohistogram);
do_file_write (filename, 4096 * 16, filesize * GB, true, dohistogram);
do_file_write (filename, 4096 * 32, filesize * GB, true, dohistogram);
do_file_write (filename, 4096, filesize * GB, false, dohistogram);
do_file_write (filename, 4096 * 2, filesize * GB, false, dohistogram);
do_file_write (filename, 4096 * 4, filesize * GB, false, dohistogram);
do_file_write (filename, 4096 * 8, filesize * GB, false, dohistogram);
do_file_write (filename, 4096 * 16, filesize * GB, false, dohistogram);
do_file_write (filename, 4096 * 32, filesize * GB, false, dohistogram);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.