我正在努力提高程序的性能,该程序同时使用Boost Graph Library和boost::bimap.分析显示大部分时间都花在内存分配和释放上.使adjacency_list图库的类boost::fast_pool_allocator显着使用改进的性能.剩下的大部分内存分配都会出现boost::bimap,所以我想尝试在那里使用自定义分配器.该文件说,你可以指定分配为bimap中的最后一个模板参数,但它并没有说什么类型的模板参数分配器本身应该是.例如,对于类型X和Y,在
boost::bimap<set_of<X>, set_of<Y>, boost::fast_pool_allocator<Z> >
Run Code Online (Sandbox Code Playgroud)
应该填写什么Z?
我为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) 我有记忆问题。我以这种方式使用结构:
包.h文件
#pragma once
#include <cstdlib>
struct Package {
char *data;
long long int *packageNumber;
long long int *allPackages;
Package(const int sizeOfData);
~Package();
};
Run Code Online (Sandbox Code Playgroud)
包.cpp
#include "Package.h"
Package::Package(const int sizeOfData) {
void *ptr = malloc(2 * sizeof(long long int) + sizeOfData * sizeof(char));
packageNumber = (long long int*) ptr;
allPackages = (long long int*) ((long long int*)ptr + sizeof(long long int));
data = (char*)((char*)ptr + 2 * sizeof(long long int));
}
Package::~Package() {
free(data);
free(packageNumber);
free(allPackages);
}
Run Code Online (Sandbox Code Playgroud)
并在方法中:
for (int …Run Code Online (Sandbox Code Playgroud) 据我所知,内存池是一个块,或者在运行时在堆栈上分配多个内存块.
相比之下,根据我的理解,从操作系统请求动态内存,然后在运行时分配在堆上.
//编辑//
据我所知,内存池的目的是提供RAM的手动管理,其中内存必须由程序员跟踪和重用.
出于多种原因,这在理论上对性能有利:
4.多线程时,单独的池允许单独的线程独立运行而无需等待共享堆(Davislor)
我对内存池的理解是否正确?如果是这样,为什么看起来内存池不经常使用?
我将Java GC测试程序移植到C++(参见下面的代码)以及Python.Java和Python的性能远远超过C++,我认为这是由于new每次都需要完成所有调用才能创建字符串.我尝试过使用Boost,fast_pool_allocator但实际上会将性能从700ms提高到1200ms.我使用分配器是错误的,还是我应该做的其他事情?
编辑:编译g++ -O3 -march=native --std=c++11 garbage.cpp -lboost_system.g ++是版本4.8.1 Python中的一次迭代大约300ms,Java大约50ms.std::allocator给出大约700ms并boost::fast_pool_allocator给出大约1200ms.
#include <string>
#include <vector>
#include <chrono>
#include <list>
#include <iostream>
#include <boost/pool/pool_alloc.hpp>
#include <memory>
//#include <gc/gc_allocator.h>
using namespace std;
#include <sstream>
typedef boost::fast_pool_allocator<char> c_allocator;
//typedef std::allocator<char> c_allocator;
typedef basic_string<char, char_traits<char>, c_allocator> pool_string;
namespace patch {
template <typename T> pool_string to_string(const T& in) {
std::basic_stringstream<char, char_traits<char>, c_allocator> stm;
stm << in;
return stm.str();
}
}
#include "mytime.hpp"
class Garbage {
public: …Run Code Online (Sandbox Code Playgroud) 假设,出于问题的目的,我们有一个内存池,最初分配了n 个块。然而,当达到容量时,池想要增长并变为原来大小的两倍 ( 2n )。
现在可以在 C 中完成此调整大小操作realloc,但是函数本身可能返回指向不同内存的指针(复制了旧数据)。
这意味着内存池分配器返回的指针可能不再有效(因为内存可能已被移动)。
克服这个问题的好方法是什么?或者说这根本有可能吗?
除了建立内存池系统,我不能在应用程序启动时为每个对象分配巨大的数组并使用它们,在极端情况下,某些对象确实需要比其实例更多的实例,所以该数组只会增加一倍或四倍的大小,所以它将再也无法达到最大大小。我需要的速度比内存还多,所以我认为这是一个公平的权衡吗?
如果我有*p = malloc(1000),我想将内存p分成200和300的块,并获取块的地址并使用它.有没有简单的方法来做到这一点?
memory-pool ×8
c++ ×6
boost ×2
c ×2
bimap ×1
boost-pool ×1
linux ×1
memory ×1
optimization ×1
performance ×1
struct ×1