Skip to content

Instantly share code, notes, and snippets.

@kshimo69
Created February 23, 2012 08:49
Show Gist options
  • Save kshimo69/1891635 to your computer and use it in GitHub Desktop.
Save kshimo69/1891635 to your computer and use it in GitHub Desktop.
簡易I/O測定ツール
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#define NUM (5)
#define ALIGNMENT_SIZE (512L)
#define ALIGNMENT_MASK (~( ALIGNMENT_SIZE - 1 ))
void print_usage() {
printf("disk_io filename bs count 0|1(flag_for_directio) 0|1(flag_for_sync)\n");
return;
}
void set_flags(int *flags, int directio, int sync) {
if (directio) {
*flags |= O_DIRECT;
}
if (sync) {
*flags |= O_SYNC;
}
return;
}
void setup_parameters(int argc, char *argv[],
int *flags_for_read, int *flags_for_write,
char **filename, size_t *blocksize, size_t *count) {
int directio, sync;
unsigned long _blocksize, _count;
if (argc != 6) {
print_usage();
exit(1);
}
*filename = argv[1];
if ( sscanf(argv[2], "%lu", &_blocksize) != 1) {
print_usage();
exit(1);
}
*blocksize = _blocksize;
if ( sscanf(argv[3], "%lu", &_count) != 1) {
print_usage();
exit(1);
}
*count = _count;
if ( sscanf(argv[4], "%d", &directio) != 1) {
print_usage();
exit(1);
}
if ( sscanf(argv[5], "%d", &sync) != 1) {
print_usage();
exit(1);
}
*flags_for_write = O_WRONLY | O_CREAT;
*flags_for_read = O_RDONLY | O_NOATIME;
set_flags(flags_for_write, directio, sync);
set_flags(flags_for_read, directio, sync);
return;
}
char *alloc_buf(char **buf_orig, char **buf, size_t count){
*buf_orig = malloc(count + ALIGNMENT_SIZE);
if ( *buf_orig == NULL ) {
perror("malloc()");
exit(2);
}
*buf = (char*)( ( (long)(*buf_orig) + ALIGNMENT_SIZE - 1 ) & ALIGNMENT_MASK );
return *buf;
}
void write_to_file(const char *filename, int flags, int mode,
const char *buf,
size_t blocksize, size_t count) {
int fd;
size_t i;
ssize_t written_bytes;
fd = open(filename, flags, mode);
if ( fd == -1 ) {
perror("close()");
exit(2);
}
for ( i = 0 ; i < count ; i++ ) {
written_bytes = write(fd, buf, blocksize);
if ( written_bytes == -1 ){
perror("write()");
exit(2);
}
if ( written_bytes < blocksize ) {
fprintf(stderr, "could write only %lu bytes.\n", (unsigned long)written_bytes);
exit(2);
}
}
if ( fsync(fd) == -1 ) {
perror("fsync()");
exit(2);
}
if ( close(fd) != 0 ) {
perror("close()");
exit(2);
}
}
void read_from_file(const char *filename, int flags, int mode,
char *buf,
size_t blocksize, size_t count) {
int fd;
size_t i;
ssize_t read_bytes;
fd = open(filename, flags, mode);
if ( fd == -1 ) {
perror("close()");
exit(2);
}
for ( i = 0 ; i < count ; i++ ) {
read_bytes = read(fd, buf, blocksize);
if ( read_bytes == -1 ){
perror("read()");
exit(2);
}
if ( read_bytes < blocksize ) {
fprintf(stderr, "could write only %lu bytes.\n", (unsigned long)read_bytes);
exit(2);
}
}
if ( close(fd) != 0 ) {
perror("close()");
exit(2);
}
}
void print_result(const char *read_or_write, const char *filename,
int flags, size_t blocksize, ssize_t count,
struct timeval *diff_tv) {
double bandwidth, diff;
diff = diff_tv->tv_sec + (double)diff_tv->tv_usec/1000000;
bandwidth = (blocksize * count) / (diff * 1024 * 1024);
printf("----------------------------------------------------------\n"
"%s result: \n"
" parameters:"
" filename=%s, O_DIRECT=%s, O_SYNC=%s\n"
" blocksize=%lu, count=%lu\n"
" performance:"
" total %s: %.1lf MBytes"
" time: %6.2lf sec\n"
" %s bindwidth: %.2lf (MBytes/sec)\n"
"----------------------------------------------------------\n",
read_or_write, filename,
((flags & O_DIRECT) ? "enabled" : "disabled"),
((flags & O_SYNC) ? "enabled" : "disabled"),
(unsigned long)blocksize, (unsigned long)count, read_or_write,
((double)blocksize * count / (1024 * 1024)),
diff, read_or_write, bandwidth);
return;
}
int main(int argc, char *argv[]) {
int flags_for_read, flags_for_write;
const int mode = 0644;
int i;
char *filename;
size_t blocksize, count;
char *buf_orig, *buf;
setup_parameters(argc, argv,
&flags_for_read, &flags_for_write,
&filename, &blocksize, &count);
alloc_buf(&buf_orig, &buf, count);
for ( i = 0 ; i < NUM ; i++ ) {
struct timeval start_tv, end_tv, diff_tv;
gettimeofday(&start_tv, NULL);
write_to_file(filename, flags_for_write, mode, buf, blocksize, count);
gettimeofday(&end_tv, NULL);
timersub(&end_tv, &start_tv, &diff_tv);
print_result("write", filename, flags_for_write, blocksize, count,
&diff_tv);
gettimeofday(&start_tv, NULL);
read_from_file(filename, flags_for_read, mode, buf, blocksize, count);
gettimeofday(&end_tv, NULL);
timersub(&end_tv, &start_tv, &diff_tv);
print_result("read", filename, flags_for_read, blocksize, count,
&diff_tv);
}
free(buf_orig);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment