c++ - 如何实现可变大小的缓存对象以减少 C++ 中的内存分配?

标签 c++ caching memory memory-pool

在表演之前人们把我的脑袋撕裂了:是的,我在问这个之前已经做了分析:)

我再次查看我的 one of a type container ,虽然我有一个可行的解决方案,但性能很差,因为缓存的每种类型的项目都会导致在堆上进行单独分配(这当然很昂贵)。

基于对我的程序输入的静态分析,我找到了一种方法来了解可能放入我的缓存对象中并被传递的所有对象所需的总大小。基本上,我有一个可以在给定缓存对象中构建的对象列表,所以我知道我可能必须提前缓存的内容的大小是多少,但不是在编译时——仅运行时。

基本上,我想做的是 boost::make_shared 所做的——获取单个内存块,并构造 shared_ptr 位以及同一内存块中的受控对象。

我不必担心保留复制行为,因为缓存对象是不可复制的并且由客户端通过指针传递(它通常存储在类似 ptr_vectorstd 的东西中: :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/

相关文章:

c++ - QTableView - 放置指针(突出显示选择到列表的第一行

c++ - 如何将 PreShutdown 事件添加到 ATL 服务?

c++ - 如何转换(指针 vector )-->(指向指针数组的指针)

android - 将 picasso 与自定义磁盘缓存一起使用

python - 获取网页的当前版本

android - 加载 Bitmap 后释放内存

c++ - 未初始化的本地字符的行为?

Android 版本不会更新 apk。有没有办法以编程方式防止缓存?

.net - 为什么 x64 中 1 个字符的 .NET 字符串是 32 个字节?

memory - Web服务器容量规划: more cores versus more memory