Last active
July 17, 2024 01:36
-
-
Save jweinst1/e5c5502a6296a42ac60a4dfcdbf390fc to your computer and use it in GitHub Desktop.
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
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <limits.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <sys/socket.h> | |
#include <sys/stat.h> | |
#include <sys/time.h> | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <assert.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <time.h> | |
static int file_exists(const char* path) { | |
struct stat buffer; | |
return stat(path, &buffer) == 0; | |
} | |
static ssize_t file_size(const char* path) { | |
struct stat sb; | |
if (stat(path, &sb) == 0) { | |
return sb.st_size; | |
} | |
return -1; | |
} | |
static void create_init_file(const char* path, size_t size) { | |
int fd = open(path, O_RDWR | O_CREAT, (mode_t)0600); | |
lseek(fd, size-1, SEEK_SET); | |
write(fd, "", 1); | |
lseek(fd, 0, SEEK_SET); | |
close(fd); | |
} | |
static size_t get_page_size(void) { | |
return sysconf(_SC_PAGE_SIZE); | |
} | |
static uint64_t time_stamp() { | |
struct timeval tv; | |
gettimeofday(&tv,NULL); | |
return tv.tv_sec*(uint64_t)1000000+tv.tv_usec; | |
} | |
#define PAGE_COUNT 100 | |
static int write_test(void) { | |
unsigned long page_size = get_page_size(); | |
printf("Using page size %lu\n", page_size); | |
const char* testfile = "foobar"; | |
char** pages = NULL; | |
create_init_file(testfile, page_size * PAGE_COUNT); | |
int fd = open(testfile, O_RDWR | O_CREAT, (mode_t)0600); | |
pages = calloc(1, sizeof(char*) * PAGE_COUNT); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
char* pagemap = malloc(page_size); | |
pages[i] = pagemap; | |
} | |
uint64_t start = time_stamp(); | |
for (size_t j = 0; j < 1000000; ++j) | |
{ | |
size_t chosen_page = j % PAGE_COUNT; | |
pages[chosen_page][j % page_size] = (char)j; | |
lseek(fd, chosen_page * page_size,SEEK_SET); | |
write(fd, pages[chosen_page], page_size); | |
} | |
uint64_t end = time_stamp(); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
free(pages[i]); | |
} | |
close(fd); | |
remove(testfile); | |
printf("The time taken for %s is %lluus\n", __FUNCTION__, end - start); | |
return 1; | |
} | |
static int mmap_test(void) { | |
unsigned long page_size = get_page_size(); | |
printf("Using page size %lu\n", page_size); | |
const char* testfile = "foobar"; | |
char** pages = NULL; | |
create_init_file(testfile, page_size * PAGE_COUNT); | |
int fd = open(testfile, O_RDWR | O_CREAT, (mode_t)0600); | |
pages = calloc(1, sizeof(char*) * PAGE_COUNT); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
char* pagemap = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, i * page_size); | |
pages[i] = pagemap; | |
} | |
uint64_t start = time_stamp(); | |
for (size_t j = 0; j < 1000000; ++j) | |
{ | |
size_t chosen_page = j % PAGE_COUNT; | |
pages[chosen_page][j % page_size] = (char)j; | |
msync(pages[chosen_page], page_size, MS_SYNC); | |
} | |
uint64_t end = time_stamp(); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
munmap(pages[i], page_size); | |
} | |
close(fd); | |
remove(testfile); | |
printf("The time taken for %s is %lluus\n", __FUNCTION__, end - start); | |
return 1; | |
} | |
static int mmap_no_sync_test(void) { | |
unsigned long page_size = get_page_size(); | |
printf("Using page size %lu\n", page_size); | |
const char* testfile = "foobar"; | |
char** pages = NULL; | |
create_init_file(testfile, page_size * PAGE_COUNT); | |
int fd = open(testfile, O_RDWR | O_CREAT, (mode_t)0600); | |
pages = calloc(1, sizeof(char*) * PAGE_COUNT); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
char* pagemap = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, i * page_size); | |
pages[i] = pagemap; | |
} | |
uint64_t start = time_stamp(); | |
for (size_t j = 0; j < 1000000; ++j) | |
{ | |
size_t chosen_page = j % PAGE_COUNT; | |
pages[chosen_page][j % page_size] = (char)j; | |
} | |
uint64_t end = time_stamp(); | |
for (size_t i = 0; i < PAGE_COUNT; ++i){ | |
munmap(pages[i], page_size); | |
} | |
close(fd); | |
remove(testfile); | |
printf("The time taken for %s is %lluus\n", __FUNCTION__, end - start); | |
return 1; | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
mmap_test(); | |
write_test(); | |
mmap_no_sync_test(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment