Skip to content

Instantly share code, notes, and snippets.

@zbjornson
Created August 31, 2019 20:30
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save zbjornson/c21a063797a29322073593d85e5e05bf to your computer and use it in GitHub Desktop.
Fast vector experiments
// Essentially a std::vector<uint8_t>, but uses mmap+mremap to manipulate the
// Linux page table. Not portable. Memory is not freed when the class is
// destructed; use FastVector::free.
// In some basic benchmarks, this is not faster than realloc (with glibc),
// although in principle it should provide better guarantees that data movement
// is avoided (regardless of alloc size).
#include <sys/mman.h>
class FastVector {
private:
void* addr_ = nullptr;
std::size_t size_ = 0;
int errno_ = 0;
public:
FastVector(std::size_t minSize) {
size_ = roundUpTo(minSize, PAGE_SIZE);
addr_ = mmap(NULL, size_, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr_ == MAP_FAILED)
errno_ = errno;
}
std::ptrdiff_t resize(std::size_t newSize, bool roundUp = true) {
if (roundUp)
newSize = roundUpTo(newSize, PAGE_SIZE);
std::size_t oldSize = size_;
addr_ = mremap(addr_, oldSize, newSize, MREMAP_MAYMOVE);
if (addr_ == MAP_FAILED) {
errno_ = errno;
return -1;
}
size_ = newSize;
return newSize - oldSize;
}
inline std::uint8_t* operator*() {
return static_cast<std::uint8_t*>(addr_);
}
inline std::size_t size() { return size_; }
inline int getErrno() { return errno_; }
static int free(void* addr, std::size_t size) {
return munmap(addr, size);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment