在表演之前人们把我的脑袋撕裂了:是的,我在问这个之前已经做了分析:)
我再次查看我的 one of a type container ,虽然我有一个可行的解决方案,但性能很差,因为缓存的每种类型的项目都会导致在堆上进行单独分配(这当然很昂贵)。
基于对我的程序输入的静态分析,我找到了一种方法来了解可能放入我的缓存对象中并被传递的所有对象所需的总大小。基本上,我有一个可以在给定缓存对象中构建的对象列表,所以我知道我可能必须提前缓存的内容的大小是多少,但不是在编译时——仅运行时。
基本上,我想做的是 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);
}
};
我的一般概念在这里听起来正确吗?有没有更好的方法来完成这个?
最佳答案
但首先,请阅读 this article by Andrei Alexandrescu关于他认为他应该在那一章中写的内容——一种使用 Heap Layers 构建堆的方法(由你真正)。我使用堆层构建 Hoard , DieHard , 和 DieHarder ,以及我们的 OOPLSA 2002 论文中使用的自定义分配器,Reconsidering Custom Memory Allocation ,在着手创建自定义分配器之前,您还应该阅读它。
关于c++ - 如何实现可变大小的缓存对象以减少 C++ 中的内存分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4730312/