c++ - Linux C++ 中的页面对齐内存分配

标签 c++ linux memory-management dynamic-memory-allocation mmu

假设,我需要在 Linux64 C++ 应用程序中分配一个大型 Vector。 我执行以下操作:

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

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

  return 0;
}

这会在我的笔记本电脑上打印出 0x7ffc2a177450,这是字对齐的。但是,Vector大小是2000*4B = 8kB,在我4kB页面的Ubuntu系统上刚好是2页。

问题:如何将 Vector 放在页面的开头,以便分配恰好在物理内存中产生 2 页?理想情况下,物理内存中的两个页面也应该是连续的。谢谢!

最佳答案

你可以定义一个页面分配器:

#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;}
  };

使用 aligned_alloc 会表现更好。

关于c++ - Linux C++ 中的页面对齐内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52576480/

相关文章:

linux - 使用 'find' 返回不带扩展名的文件名

linux - 如何将nohup pid输出到top命令?

python - 我怎样才能找到virtualenv python的路径

c++ - 本地类变量位置

c++ - Direct2D 中的双缓冲?

c++ - 下载速度到处跳

c++ - 在 C++ 中输入空白行之前,如何要求用户输入整数?

c - 使用双指针为结构内的动态结构数组分配内存**

android - 为什么 Android 和 iOS 不在应用关闭时杀死进程?

c++如何让函数参数采用不同的对象(但属于同一类)并访问通过w/n函数调用传递的w/e对象的函数?