2

ここのどこかで、Loki の Small Object Allocator for Lua を使用して割り当てのパフォーマンスを向上させることを誰かが推奨している記事を読んだことがあります。「Modern C++ Design」のセクションを読みましたが、Loki を使用しないことを除いて、これに Loki を使用することについて十分に理解していると思いますSmallObject。直接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 の場合
 ローカル テスト = { }
終わり

何が問題なのか、これをどのように診断し、どのように修正すればよいですか?

4

2 に答える 2

4

私が思いついた問題は、カスタム アロケータが C のrealloc()関数のように動作する必要があるということです。osize != nsizeこれは、および 両方が非ゼロの場合に重要です。この場合の の重要な特性は、古いブロックrealloc()の最初のバイトの値をmin(osize,nsize)新しいブロックの先頭として保持することです。

あなたが持っている:

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

古い割り当てのすべての内容を破棄します。

これは指定されています

アロケータ関数は、realloc と同様の機能を提供する必要がありますが、まったく同じではありません。

lua_Allocのドキュメントにあります。

于 2009-07-09T07:40:05.267 に答える
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()..の場合にあると思われます。

于 2009-07-09T18:50:57.290 に答える