2012-04-28 10 views
12

¿Hay alguna madurar C/C++, capaz de optimizar malloc/free (o new/delete) pares alloca información? En otras palabras, convierta de memoria basada en pila a basada en pila (SOLAMENTE para algunos casos limitados).Will compilador optimizar malloc/libre o nuevos/borrar par en alloca

Esta optimización solo puede permitirse para un par de malloc/free cuando ambas funciones están en la misma función (o incluso en el mismo bloque de {}), y se invoca a free cada vez que se invoca malloc. Además, consideremos que el puntero a la memoria mal colocada no se guarda en alguna variable global.

Así, se GCC/LLVM + sonido metálico/Intel Compiler convertir tales bloque de código:

{ 
    char *carray; 
    carray = malloc(100);   // or malloc(N) 
    // some string-like work with carray 
    free(carray); 
} 

en

{ 
    char*carray; 
    carray = alloca(100); // or if(N<const1) carray=alloca(N);else carray=malloc(N) 
    // the same work 
    // nothing      // or if(N>=const1) free(carray) 
} 

Esta conversión puede no ser muy útil para todos los programas, pero creo , puede haber alguna opción de compilador especial.

PS (Update1) Podemos limitar nuestra discusión sólo para los casos en que el compilador sabe que malloc y libre es de libc (stdlib)

+1

Hace un año un hombre en la lista llvm [dijo no] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/032971.html) y otro hombre [dijo sí] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033015.html) y apunta a [código real] (http: //lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033017.html) – osgx

+3

Creo que malloc no es intrínseco. Y es bastante peligroso hacerlo, ya que el compilador no tiene información sobre el tamaño de la pila en tiempo de ejecución. – BlueWanderer

+0

La transformación no es segura si se llama a cualquier otra función cuyo compilador no puede ver la definición y se pasa el resultado de malloc: la función puede almacenar el puntero en algún lugar y luego omitir el libre por 'longjmp' (C, generalmente) o excepción (C++). Sospecho, teniendo esto en cuenta, que la transformación es menos útil de lo que imaginas. – hvd

Respuesta

2

Técnicamente, los compiladores pueden optimizar cualquier cosa, siempre y cuando sigan las Como-Si regla.
Por lo tanto, optimizar las asignaciones de montón a las asignaciones de la pila sería posible, pero el compilador debe ser lo suficientemente inteligente como para probar el uso y determinar que cambiar la asignación a la pila no afectará el comportamiento observable del programa.

No conozco ningún compilador que haga esto.

10

En general, ningún compilador realiza esta optimización. Eso es bueno, porque esto puede ser potencialmente muy dañino: tenga en cuenta que la pila suele tener un tamaño muy limitado. Si un compilador optimizado malloc + free en un alloca, el comportamiento observable del código podría cambiar: para algunos insumos, no se estrellaría con malloc + free, pero sería con alloca (debido a que el espacio de pila quedó agotada). Por lo tanto, esta optimización es insegura (e ilegal según el estándar, porque cambia el comportamiento observable) y los compiladores ni siquiera intentan realizarla.

Dicho esto, en algunas circunstancias muy específicas, un compilador podría realizarlo, pero ningún compilador del que yo tenga conocimiento.

La optimización realizada por LLVM y mencionados en the comments es una cosa diferente, sólo se optimiza a cabo malloc s que sólo se comparan en nulo y luego free d.

+0

En realidad, llvm 3.0 hace una optimización similar (memoria mal ubicada -> registro), si malloc y free se usan para almacenar valores escalares (el doble en mi prueba). Pero no optimizó el ejemplo con 100 char array – osgx

+0

@osgx: aún no es 'malloc' ->' alloca', – Fanael

+2

Su argumento asume que el tamaño de la pila puede agotarse en situaciones en las que malloc tendría éxito. Eso no es necesariamente cierto. Los sistemas pueden permitir que el tamaño de la pila se expanda según sea necesario, o más raramente, no usan una pila lineal en absoluto. – hvd

7

Hay un off-shoot de LLVM llamado poolalloc que hace esta optimización. Se mantiene como parte de SAFECode y no se encuentra en la distribución LLVM principal.

Es descrito en Doctorado Chris Lattner 's thesis y en this papel PLDI. El código es here.

Cuestiones relacionadas