WiscSort / pmem_benchmark / mmapBWTest.c
mmapBWTest.c
Raw
#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));
}