1 #include "benchmark/benchmark_api.h"
16 static const size_t pageSize = PAGE_SIZE;
17 static size_t fsize = 1024 * (1ull << 20);
18 static size_t pagesTotal = fsize / pageSize;
23 int get() { return m_fd; }
24 void set(int fd) { m_fd = fd; }
26 explicit Fd(int fd) : m_fd{fd} {}
35 void fillPageJunk(void *ptr)
37 uint64_t seed = (unsigned long long)rand() | ((unsigned long long)rand() << 32);
38 uint64_t *target = (uint64_t*)ptr;
39 for (int i = 0; i < pageSize / sizeof(uint64_t); i++) {
40 *target = seed ^ (uint64_t)(uintptr_t)target;
41 seed = (seed << 1) | ((seed >> 63) & 1);
49 void *m_ptr = nullptr;
57 FileMap(const string &name, size_t size, Hint hint = FILE_MAP_HINT_NONE) : m_name{name}, m_size{size} {
58 int fd = open(name.c_str(), O_CREAT | O_RDWR, S_IRWXU);
60 cout << "Error: open failed for " << name << ": " << strerror(errno) << endl;
64 fallocate(m_fileFd.get(), 0, 0, size);
66 m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fileFd.get(), 0);
67 if ((int)(uintptr_t)m_ptr == -1) {
68 cout << "Error: mmap failed: " << (int)(uintptr_t)m_ptr << ": " << strerror(errno) << endl;
72 case FILE_MAP_HINT_NONE: break;
73 case FILE_MAP_HINT_RAND:
74 madvise(m_ptr, m_size, MADV_RANDOM);
76 case FILE_MAP_HINT_LINEAR:
77 madvise(m_ptr, m_size, MADV_SEQUENTIAL);
80 for (int i = 0; i < m_size / pageSize; i++) {
81 uint8_t *targetPtr = (uint8_t*)m_ptr + 4096ull * i;
82 fillPageJunk(targetPtr);
85 void benchRandomRead(unsigned int targetPage) {
86 uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * targetPage;
89 void benchRandomWrite(unsigned int targetPage) {
90 uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * targetPage;
93 void benchLinearRead(unsigned int j) {
94 uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * j;
97 void benchLinearWrite(unsigned int j) {
98 uint8_t *targetPtr = (uint8_t*)m_ptr + pageSize * j;
102 int ret1 = msync(m_ptr, m_size, MS_SYNC | MS_INVALIDATE);
103 madvise(m_ptr, m_size, MADV_DONTNEED);
108 munmap(m_ptr, m_size);
113 static void benchRandomRead(benchmark::State& state) {
114 FileMap file{"/data/local/tmp/mmap_test", fsize};
115 while (state.KeepRunning()) {
116 unsigned int targetPage = rand() % pagesTotal;
117 file.benchRandomRead(targetPage);
119 state.SetBytesProcessed(state.iterations() * pageSize);
121 BENCHMARK(benchRandomRead);
123 static void benchRandomWrite(benchmark::State& state) {
124 FileMap file{"/data/local/tmp/mmap_test", fsize};
125 while (state.KeepRunning()) {
126 unsigned int targetPage = rand() % pagesTotal;
127 file.benchRandomWrite(targetPage);
129 state.SetBytesProcessed(state.iterations() * pageSize);
131 BENCHMARK(benchRandomWrite);
133 static void benchLinearRead(benchmark::State& state) {
134 FileMap file{"/data/local/tmp/mmap_test", fsize};
136 while (state.KeepRunning()) {
137 file.benchLinearRead(j);
138 j = (j + 1) % pagesTotal;
140 state.SetBytesProcessed(state.iterations() * pageSize);
142 BENCHMARK(benchLinearRead);
144 static void benchLinearWrite(benchmark::State& state) {
145 FileMap file{"/data/local/tmp/mmap_test", fsize};
147 while (state.KeepRunning()) {
148 file.benchLinearWrite(j);
149 j = (j + 1) % pagesTotal;
151 state.SetBytesProcessed(state.iterations() * pageSize);
153 BENCHMARK(benchLinearWrite);