我正在编写一个性能关键型应用程序,我在其中创建大量类似类型的对象来下订单.我使用boost :: singleton_pool来分配内存.最后我的班级看起来像这样.
class MyOrder{
std::vector<int> v1_;
std::vector<double> v2_;
std::string s1_;
std::string s2_;
public:
MyOrder(const std::string &s1, const std::string &s2): s1_(s1), s2_(s2) {}
~MyOrder(){}
static void * operator new(size_t size);
static void operator delete(void * rawMemory) throw();
static void operator delete(void * rawMemory, std::size_t size) throw();
};
struct MyOrderTag{};
typedef boost::singleton_pool<MyOrderTag, sizeof(MyOrder)> MyOrderPool;
void* MyOrder:: operator new(size_t size)
{
if (size != sizeof(MyOrder))
return ::operator new(size);
while(true){
void * ptr = MyOrderPool::malloc();
if (ptr != NULL) return ptr; …
Run Code Online (Sandbox Code Playgroud) 所以我memory_pools
基于boost池创建了这个容器分配器类:
memory_pools.hpp
#ifndef MEMORY_POOL_HPP
# define MEMORY_POOLS_HPP
// boost
# include <boost/pool/pool.hpp>
# include <boost/unordered_map.hpp>
template<typename ElementType>
class memory_pools
{
public:
template <typename>
friend class memory_pools;
private:
using pool = boost::pool<>;
public:
using value_type = ElementType;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using size_type = pool::size_type;
using difference_type = pool::difference_type;
public:
template<typename OtherElementType>
struct rebind
{
using other = memory_pools<OtherElementType>;
};
public:
memory_pools();
template<typename SourceElement>
memory_pools(const …
Run Code Online (Sandbox Code Playgroud) 我希望有一个std::vector
对象,使用分配的对象boost::pool
.这是正确的:
class MyClass
{
private:
double data;
public:
MyClass(double d) : data(d) { }
};
int main()
{
std::vector<MyClass, boost::fast_pool_allocator<MyClass> > vect;
vect.push_back(4.5);
vect.push_back(9.8); //Are these being stored in a pool now?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效,但我不完全确定原因.我对分配器的概念很陌生,但是如果我理解正确的话,这就是std::vector
使用池而不是默认分配器,因此在向量中创建的任何元素都将从池中创建.
我不太确定的是:
游泳池在哪里?
我将如何直接访问池(例如释放内存)?
是否fast_pool_allocator
包含池,或者我是否需要单独创建池并以某种方式告诉分配器使用它.
我是新手,我想知道boost :: pool库如何帮助我创建自定义内存分配器.我有两个struct对象向量.第一个向量是结构类型A,而第二个向量是结构类型B.我如何重用分配给第一个向量的内存到第二个向量.
我为MyOrder类编写了自定义运算符new和operator delete.我使用boost :: singleton pool分配内存.这是测试性能的程序,
#include <boost/pool/singleton_pool.hpp>
#include <boost/progress.hpp>
#include <iostream>
#include <new>
#include <vector>
class MyOrder{
std::vector<int> v1_;
std::vector<double> v2_;
std::string s1_;
std::string s2_;
public:
MyOrder(std::string s1, std::string s2): s1_(s1), s2_(s2) {}
~MyOrder(){}
static void * operator new(size_t size);
static void operator delete(void * rawMemory) throw();
};
struct MyOrderTag{};
typedef boost::singleton_pool<MyOrderTag, sizeof(MyOrder)> MyOrderPool;
void* MyOrder:: operator new(size_t size)
{
if (size != sizeof(MyOrder))
return ::operator new(size);
while(true){
void * ptr = MyOrderPool::malloc();
if (ptr != NULL) return ptr;
std::new_handler …
Run Code Online (Sandbox Code Playgroud) 背景
我先前的问题有关boost.pool
促使我详细调查boost.pool,现在我有一个补充问题,最后确定我的理解.
序幕
此参考说明了有关对象池模式的以下内容:
对象池模式是一种软件创建设计模式,它使用一组准备好使用的初始化对象,而不是按需分配和销毁它们.
据我所知,boost.pool
(简化)通过内存分配和管理实现对象池模式,主要基于a的大小element_type
,并返回一个指向已分配对象的简单指针:
element_type * malloc();
void free(element_type * p);
Run Code Online (Sandbox Code Playgroud)
一个简单的提升示例还表明,没有必要明确free
获取的元素:
X * const t = p.malloc();
... // Do something with t; don't take the time to free() it.
Run Code Online (Sandbox Code Playgroud)
题
我知道在破坏池对象时可以安全地释放分配的内存,但是池如何知道客户端获取的内存块何时被释放回池中并且如果其接口提交直接指针则可以重用到element_type
,但free()
仍然不需要打电话?也就是说,如果无法确定内存是否仍在使用中,那么增强池如何重新使用此内存?如果它不重用这个内存,这甚至被认为是与wiki引用解释的模式相同的模式?
我使用boost池作为静态内存提供程序,
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们如何修复池的大小,我的意思是我们知道boost :: pool提供了一个静态内存分配器,但是我无法修复这个池的大小,它不断增长,应该有办法限制其规模.例如,我只想要一个200块的池,所以我可以采取200块之后,它应该虽然为NULL请让我现在如何做到这一点
我的印象是,a object pool
是一种设计模式,用于管理客户端可以请求的一组预分配对象,并返回其中一个对象.然而,似乎boost.pool
的object_pool
类更多的是用较低级存储器管理不是目标管理.他们为什么选择这个名字,而不是像memory_pool
?我是否认为boost的对象池实际上是一个内存池方案?或者它们基本上是一回事?另外,为什么还没有更高级别的对象池模式的标准实现?
我有以下简单的测试代码.
#include <stack>
#include <iostream>
#include "boost/pool/pool_alloc.hpp"
struct Frame
{
uint32_t i{};
Frame(uint32_t _i) : i(_i) {}
Frame(const Frame& f)
{
std::cout << "Copy constructor" << std::endl;
i = f.i;
}
Frame(Frame&& f)
{
std::cout << "Move constructor" << std::endl;
std::swap(i, f.i);
}
};
int main(int argc, char* argv[])
{
{
std::stack<Frame, std::deque<Frame>> stack;
Frame f(0);
stack.push(std::move(f)); // Move constructor
stack.push(Frame(1)); // Move constructor
}
{
std::stack<Frame, std::deque<Frame, boost::pool_allocator<Frame>>> stack;
Frame f(0);
stack.push(std::move(f)); // Copy constructor
stack.push(Frame(1)); // Copy constructor …
Run Code Online (Sandbox Code Playgroud) 我正在学习内存池,并尝试boost::pool_allocator
在我的项目中使用。根据文档,我做了一个关于时间成本的小测试:
template <typename Alloc>
void test()
{
using namespace std::chrono;
auto t0 = high_resolution_clock::now();
for (int i = 0; i < 1000; ++i) {
std::vector<int, Alloc> vec;
for (int j = 0; j < 10000; ++j)
vec.push_back(i + j);
}
auto t1 = high_resolution_clock::now();
auto time_ms = duration<double>(t1 - t0).count() * 1e3;
cout << "time cost: " << time_ms << " ms" << endl;
}
int main()
{
test<std::allocator<int>>();
test<boost::pool_allocator<int>>();
}
Run Code Online (Sandbox Code Playgroud)
结果是:
time cost: 3.97602 ms …
Run Code Online (Sandbox Code Playgroud) boost-pool ×10
c++ ×10
boost ×5
allocator ×2
c++11 ×2
memory-pool ×1
objectpool ×1
performance ×1
vector ×1