#include <sys/mman.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <time.h> #include <assert.h> #define NS_IN_SECOND 1000000000 #define TEN_GB_IN_BYTES 10737418240 #define ONE_GB_IN_BYTES 1073741824 //#define BLOCK_SIZE 4096 #define READ 1 #define WRITE 2 #define NANOSECONDS_IN_SECOND 1000000000 #define BYTES_IN_GB (1024*1024*1024) extern __inline__ uint64_t rdtsc(void) { uint64_t a, d; double cput_clock_ticks_per_ns = 2.6; //2.6 Ghz TSC uint64_t c; __asm__ volatile ("rdtscp" : "=a" (a), "=c" (c), "=d" (d) : : "memory"); return ((d<<32) | a)/cput_clock_ticks_per_ns; } uint64_t nano_time(void) { struct timespec ts; if( clock_gettime(CLOCK_REALTIME, &ts) == 0) return ts.tv_sec * NS_IN_SECOND + ts.tv_nsec; } size_t get_filesize(const char* filename){ int retval; struct stat st; retval = stat(filename, &st); if(retval) return -1; else return st.st_size; } int main(int argc, char** argv){ char* op = argv[1]; char* bs = argv[2]; char* fs = argv[3]; int optype = atoi(op); uint64_t block_size = (uint64_t)atoi(bs); uint64_t filesize = get_filesize(fs); assert(filesize != -1); char *mmapped_buffer = NULL, *buffer = NULL; uint64_t i, ret; uint64_t begin_time, end_time, ret_token = 0; // open file uint64_t mode = S_IRWXU | S_IRWXG; int flags = O_RDWR; int fd = open((const char*)fs, flags, mode); // create buffer to write from uint64_t map_time = rdtsc(); // ANON POPULATE // mmapped_buffer = (char*)mmap(NULL, filesize, // PROT_READ | PROT_WRITE, // MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS, -1, 0); // /* With MAP_POPULATE */ mmapped_buffer = (char*)mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); // /* With MAP_SHARED */ // mmapped_buffer = (char*)mmap(NULL, filesize, // PROT_READ | PROT_WRITE, // MAP_SHARED, fd, 0); map_time = rdtsc() - map_time; printf("Finished map init =================\n"); if (mmapped_buffer == MAP_FAILED) { printf("Failed to mmap file of size %" PRIu64 ": %s\n", (uint_least64_t)filesize, strerror(errno)); return -1; } buffer = (char*)malloc(block_size); if(buffer == NULL) { printf("Failed to allocate memory: %s\n", strerror(errno)); return -1; } memset((void*)buffer, 1, block_size); begin_time = nano_time(); // begin_time = rdtsc(); // for(i = 0; i < filesize/block_size; i++){ for(i=0; i<filesize; i+=block_size){ //printf("%ld == %ld\n",i, filesize); if(optype == READ) { memcpy(buffer, &mmapped_buffer[i], block_size); ret_token += buffer[0]; } else if (optype == WRITE) { memcpy(&mmapped_buffer[i], buffer, block_size); // Arbitrary operation. ret_token += mmapped_buffer[i]; } } end_time = nano_time(); // end_time = rdtsc(); // printf("%s: %" PRIu64 " bytes in %" PRIu64 " ns.\n", // (optype==READ)?"readmap":"writemap", // (uint_least64_t)filesize, (end_time-begin_time)); // print GB/s printf("\t%.2f\n", (double)filesize/(double)(end_time-begin_time) * NANOSECONDS_IN_SECOND / BYTES_IN_GB); printf("\t mmap init itme: %lu \n", map_time); // Unmap your file ret = munmap(mmapped_buffer, filesize); if(ret) printf("Error unmapping file: %s\n", strerror(errno)); }