WiscSort / pmem_benchmark / bw2.c
bw2.c
Raw
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <time.h>
#define NS_IN_SECOND 1000000000
#define TEN_GB_IN_BYTES 10737418240
//#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;
}

int main(int argc, char** argv){

    uint64_t filesize = TEN_GB_IN_BYTES;
    char* op = argv[1];
    char* bs = argv[2];
    int optype = atoi(op);
    int block_size = atoi(bs);
    char *mmapped_buffer = NULL, *buffer = NULL;
    uint64_t i, ret;
    uint64_t begin_time, end_time, ret_token = 0;
    // open file
    char* fname = "/mnt/pmem/10mmaptest";
    uint64_t mode = S_IRWXU | S_IRWXG;
    int flags = O_RDWR;
    int fd = open((const char*)fname, flags, mode);
    // create buffer to write from
    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);

//    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_PRIVATE | MAP_POPULATE, fd, 0);
//   /* With MAP_SHARED */
//     mmapped_buffer = (char*)mmap(NULL, filesize,
//                      PROT_READ | PROT_WRITE,
//                       MAP_SHARED, fd, 0);

    if (mmapped_buffer == MAP_FAILED) {
        printf("Failed to mmap file of size %" PRIu64 ": %s\n",
                (uint_least64_t)filesize, strerror(errno));
        return -1;
    }
    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 read 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);

    // Unmap your file
    ret = munmap(mmapped_buffer, filesize);
    if(ret)
        printf("Error unmapping file: %s\n", strerror(errno));
}