如何实现可变大小的缓存对象以减少C ++中的内存分配?
在表演之前,人们会把我的脑袋撕掉:是的,我在问这个之前做过剖析:)
我再次看到我的一个类型容器,虽然我有一个有效的解决方案,但性能很差,因为缓存的每种类型的项都会导致堆上的单独分配(这当然是昂贵的)。
基于对程序输入的静态分析,我找到了一种方法来了解可能放在我的缓存对象中的所有对象所需的总大小。基本上,我有一个可以在给定缓存对象中构造的对象列表,所以我知道我可能需要缓存的大小是什么,而不是在编译时 - 仅运行时。
基本上,我想要做的是
boost::make_shared
做什么 - 获取单个内存块,并在同一个内存块中构造shared_ptr
位以及受控对象。
我不必担心保留复制行为,因为缓存对象是不可复制的并且由客户端通过指针传递(它通常存储在类似ptr_vector
或std::auto_ptr
的东西中)。
然而,我并不熟悉如何实现这样的容器,即如何遵循对齐限制等。
在伪代码中,我想做什么:
//I know a lot of what's in here is not portable -- I need to run only on x86
//and x64 machines. Yes, this couple of classes looks hacky, but I'd rather
//have one hacky class than a whole programfull :)
class CacheRegistrar
{
//Blah blah
public:
//Figures out what objects will be in the cache, etc
const std::vector<std::size_t>& GetRequiredObjectSizes() const;
//Other stuff...
template <typename T>
void RegisterCacheObject();
template <typename T>
std::size_t GetObjectIndex() const;
// etc.
};
class CacheObject;
std::auto_ptr<CacheObject> CacheObjectFactory(const CacheRegistrar& registrar)
{
//Pretend this is in a CPP file and therefore CacheObject is defined...
const std::vector<size_t>& sizes(registrar.GetRequiredObjectSizes());
std::size_t sumOfCache = std::accumulate(sizes.begin(), sizes.end());
sumOfCache += sizeof(CacheObject);
boost::scoped_array<char> buffer(new char[] sumOfCache);
CacheObject *obj = new (reinterpret_cast<void *>(buffer.get())) CacheObject;
buffer.release(); //PSEUDOCODE (boost::scoped_array has no release member);
return std::auto_ptr<CacheObject>(obj); //Nothrow
}
class CacheObject
{
CacheRegistrar *registrar; //Set by my constructor
public:
template<typename T>
T& Get()
{
char * startOfCache = reinterpret_cast<char *>(this) +
sizeof(CacheObject);
char * cacheItem = startOfCache + registrar->GetObjectIndex<T>();
return *reinterpret_cast<T*>(cacheItem);
}
};
这是我的一般概念吗?有没有更好的方法来实现这一目标?
没有找到相关结果
已邀请:
3 个回复
粱委教
杰黔轿缺
曝匿弄罚