Pregunta

He leído en algún lugar aquí donde alguien recomienda el uso de Pequeño asignador de objetos de Loki para LUA para ayudar a mejorar el rendimiento de la asignación. He leído a través de la sección en 'Modern C Diseño ++' y creo que tengo una lo suficientemente bueno entender sobre el uso de Loki para esto, con la excepción de no usar el SmallObject - Lua sólo quiere memoria prima, así que tomé un primer intento utilizando directamente la SmallObjAllocator.

Las asignaciones parecen que están trabajando, pero todo falla por completo una vez traté de cargar un script (ya sea usando lua_load() con mi propio lector de encargo, o el uso de luaL_loadfile() para leer el archivo directamente).

Aquí está mi implementación de la clase 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);

Y cuando se crea el estado de Lua, le doy la función de asignación que utiliza este nuevo asignador:

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;
}

Y aquí voy a cargar el archivo:

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

Si tengo un lazo simple for en Global.lua el sistema nunca regresa de la llamada a luaL_loaloadfile():

for i=1,100 do
 local test = { }
end

Lo que está mal, ¿cómo debo diagnosticar esta, y cómo lo arreglo?

¿Fue útil?

Solución

El problema que salta a mí es que el asignador de encargo tiene que comportarse como función de realloc() C. Esto es crítico en el caso en osize != nsize y ambos no son cero. La propiedad clave de realloc() en este caso es que conserva los valores de los primeros bytes min(osize,nsize) del antiguo bloque como el comienzo del nuevo bloque.

Usted tiene:

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

, que abandona todo el contenido de la edad de la asignación.

Esto se especifica

  

La función de asignación debe proporcionar una   una funcionalidad similar a REALLOC, pero   no es exactamente la misma.

en la documentación de lua_Alloc .

Otros consejos

Bien dicho! Realmente no entiendo lo que realloc () lo hice, así que me puse en el camino correcto. He sustituido la parte reasignación para el código de abajo y todo funciona ahora, pero mi rendimiento en este momento es en realidad un poco peor que el uso de la HeapAlloc / HeapReAlloc / HeapFree que tenía antes.

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

Sospecho que un problema se debe a que Loki utiliza malloc / libre para cada bloque, así como cuando el tamaño es> GetMaxObjectSize () ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top