假设,我需要在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个页面中产生?理想情况下,物理内存中的两个页面也应该是连续的。谢谢!
答案 0 :(得分:5)
您可以定义页面分配器:
#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会更好。