Created
February 23, 2012 08:49
-
-
Save kshimo69/1891635 to your computer and use it in GitHub Desktop.
簡易I/O測定ツール
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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