Распределение памяти по страницам в Linux C ++ - PullRequest
0 голосов
/ 30 сентября 2018

Предположим, мне нужно выделить большой вектор в приложении Linux64 C ++.Я делаю следующее:

int main()
{
  std::vector<int> v;
  v.resize(2000);

  std::cout << &v[0] << std::endl;

  return 0;
}

Это печатает 0x7ffc2a177450 на моем ноутбуке, который выровнен по словам.Тем не менее, размер вектора составляет 2000 * 4B = 8 КБ, что соответствует 2 страницам в моей системе Ubuntu на 4 КБ страницы.

Вопрос. Как поместить вектор в начало страницы, чтобы распределениеровно 2 страницы в физической памяти?В идеале обе страницы в физической памяти также должны быть непрерывными.Спасибо!

1 Ответ

0 голосов
/ 30 сентября 2018

Вы можете определить распределитель страниц:

#include <sys/user.h>
#include <sys/mman.h>
#include <cstddef>
#include <new>
template<class T>
struct page_allocator{
    using value_type = T;
    static auto mem_size_for(std::size_t n){
      n = n * sizeof(T);
      return (n & (PAGE_MASK)) + (n & ~(PAGE_MASK) ? PAGE_SIZE:0);
      }
    T* allocate(std::size_t n){
      auto p = mmap(0, mem_size_for(n)
                   ,PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
      if (p==MAP_FAILED) throw std::bad_alloc{};
      return static_cast<T*>(p);
      }
    void deallocate(T* p,std::size_t n){
      munmap(p,mem_size_for(n));
      }
    constexpr bool operator==(page_allocator)noexcept{return true;}
    constexpr bool operator!=(page_allocator)noexcept{return false;}
  };

И использовать его следующим образом:

int main()
{
  std::vector<int,page_allocator<int>> v;
  v.resize(PAGE_SIZE/sizeof(int));

  std::cout << &v[0] << std::endl;

  return 0;
}

Другой вариант, используя posix_memalign:

#include <cstddef>
#include <new>
#include <stdlib.h>
template<class T>
struct memalign_allocator{
    using value_type = T;
    T* allocate(std::size_t n){
      void* p;
      if (posix_memalign(&p,PAGE_SIZE,n*sizeof(T))) throw std::bad_alloc{};
      return static_cast<T*>(p);
      }
    void deallocate(T* p,std::size_t n){
      free(p);
      }
    constexpr bool operator==(memalign_allocator)noexcept{return true;}
    constexpr bool operator!=(memalign_allocator)noexcept{return false;}
  };

Использованиеalign_alloc будет работать лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...