如何在Lua中成功使用Loki的小对象分配器?

问题描述 投票:0回答:2

我在这里读过,有人建议使用 Loki 的 Lua 小对象分配器来帮助提高分配性能。我通读了“现代 C++ 设计”中的部分,我认为我对使用 Loki 来实现这一点已经有了足够的了解,除了不使用

SmallObject
- Lua 只需要原始内存,所以我首先选择了直接使用
SmallObjAllocator

分配似乎正在工作,但是一旦我尝试加载脚本(使用

lua_load()
和我自己的自定义阅读器,或者使用
luaL_loadfile()
直接读取文件),一切都完全失败。

这是我对

SmallObjAllocator
类的实现:

class MySmallAllocator : public Loki::SmallObjAllocator
{
  public:
    MySmallAllocator( std::size_t pageSize, 
                      std::size_t maxObjectSize, 
                      std::size_t objectAlignSize ) : Loki::SmallObjAllocator( pageSize, maxObjectSize, objectAlignSize ) 
    { 
    }
    virtual ~MySmallAllocator() 
    { 
    }
};
static MySmallAllocator alloc_(4096,64,4);

当我创建 Lua 状态时,我给它使用这个新分配器的分配函数:

masterState_ = lua_newstate(customAlloc_, &heap_);

void* customAlloc_( void* ud, void* ptr, size_t osize, size_t nsize )
{
  // If the new size is zero, we're destroying a block
  if (nsize == 0)
  {
    alloc_.Deallocate( ptr );
    ptr = NULL;
  }
  // If the original size is zero, then we're creating one
  else if (0 != nsize && 0 == osize)
  {
    ptr = alloc_.Allocate( nsize, false );
  }
  else
 {
   alloc_.Deallocate( ptr );
   ptr = alloc_.Allocate( nsize, false );
 }

 return ptr;
}

我在这里加载文件:

int result = luaL_loadfile( masterState_, "Global.lua" );

如果我在 Global.lua 中有一个简单的

for
循环,系统永远不会从对
luaL_loaloadfile()
的调用中返回:

对于 i=1,100 做
 本地测试 = { }
结尾

出了什么问题,我应该如何诊断,以及如何修复它?

memory-management lua c++-loki
2个回答
4
投票

我突然想到的问题是您的自定义分配器需要像 C 的

realloc()
函数一样运行。这在
osize != nsize
和 都非零的情况下至关重要。在这种情况下
realloc()
的关键属性是它保留旧块的前
min(osize,nsize)
字节的值作为新块的开始。

你有:

    else
    {
            alloc_.Deallocate( ptr );
            ptr = alloc_.Allocate( nsize, false );
    }

放弃旧分配的所有内容。

这是指定的

分配器函数必须提供 功能类似于 realloc,但是 不完全一样。

lua_Alloc 的文档中。


0
投票

打得好!我真的不明白 realloc() 做了什么,所以你让我走上了正确的道路。我将重新分配部分替换为下面的代码,现在一切正常,但我现在的性能实际上比之前使用 HeapAlloc/HeapReAlloc/HeapFree 差一点。

    void* replacementPtr = alloc_.Allocate( nsize, true );
    memcpy( replacementPtr, ptr, min(osize, nsize) );
    alloc_.Deallocate( ptr );
    ptr = replacementPtr;

我怀疑一个问题是因为 Loki 对每个块使用 malloc/free 以及当大小 > GetMaxObjectSize() 时...

© www.soinside.com 2019 - 2024. All rights reserved.