compiler c gcc

compiler - makefile



¿Qué mejoras ofrece GCC''s__builtin_malloc() `sobre el` malloc() `? (1)

Recientemente me __builtin_malloc() funciones integradas de GCC para algunas de las funciones de administración de memoria de la biblioteca C, específicamente __builtin_malloc() y las incorporaciones relacionadas (consulte https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html ). Al __builtin_malloc() de __builtin_malloc() , me preguntaba cómo podría funcionar para proporcionar mejoras de rendimiento en las rutinas de la biblioteca relacionadas con malloc() .

Por ejemplo, si la función tiene éxito, debe proporcionar un bloque que puede ser liberado por una llamada a plain free() ya que el puntero puede ser liberado por un módulo compilado sin __builtin_malloc() o __builtin_free() habilitado (o am Me equivoqué al respecto, y si se __builtin_malloc() , ¿se deben usar las incorporaciones globalmente?). Por lo tanto, el objeto asignado debe ser algo que pueda gestionarse con las estructuras de datos con las que lidian malloc() y free() .

No puedo encontrar ningún detalle de cómo funciona __builtin_malloc() o qué es exactamente lo que hace (no soy un compilador de desarrolladores, por lo que no estoy en el __builtin_malloc() código GCC). En algunas pruebas simples en las que he intentado llamar a __builtin_malloc() directamente, simplemente termina siendo emitido en el código del objeto como una llamada a malloc() normal. Sin embargo, podría haber sutileza o detalles de la plataforma que no estoy proporcionando en estas simples pruebas.

¿Qué tipo de mejoras de rendimiento puede __builtin_malloc() proporcionar en una llamada a plain malloc() ? ¿Tiene __builtin_malloc() una dependencia de las estructuras de datos bastante complejas que utiliza la implementación malloc() glibc? O a la inversa, ¿tiene malloc() / free() glibc algún código para lidiar con los bloques que pueden ser asignados por __builtin_malloc() ?

Básicamente, ¿cómo funciona?


Creo que no hay una implementación interna especial de GCC de __builtin_malloc() . Más bien, existe solo como una función integrada, por lo que se puede optimizar en ciertas circunstancias.

Tomemos este ejemplo:

#include <stdlib.h> int main(void) { int *p = malloc(4); *p = 7; free(p); return 0; }

Si deshabilitamos las incorporaciones (con -fno-builtins ) y miramos la salida generada:

$ gcc -fno-builtins -O1 -Wall -Wextra builtin_malloc.c && objdump -d -Mintel a.out 0000000000400580 <main>: 400580: 48 83 ec 08 sub rsp,0x8 400584: bf 04 00 00 00 mov edi,0x4 400589: e8 f2 fe ff ff call 400480 <malloc@plt> 40058e: c7 00 07 00 00 00 mov DWORD PTR [rax],0x7 400594: 48 89 c7 mov rdi,rax 400597: e8 b4 fe ff ff call 400450 <free@plt> 40059c: b8 00 00 00 00 mov eax,0x0 4005a1: 48 83 c4 08 add rsp,0x8 4005a5: c3 ret

Las llamadas a malloc / free son emitidas, como se espera.

Sin embargo, al permitir que malloc sea ​​una función incorporada,

$ gcc -O1 -Wall -Wextra builtin_malloc.c && objdump -d -Mintel a.out 00000000004004f0 <main>: 4004f0: b8 00 00 00 00 mov eax,0x0 4004f5: c3 ret

Todo lo main() fue optimizado lejos!

Esencialmente, al permitir que malloc sea ​​una función integrada, GCC es libre de eliminar llamadas si su resultado nunca se usa, porque no hay efectos secundarios adicionales.

Es el mismo mecanismo que permite que las llamadas "derrochadas" a printf se cambien a llamadas a puts :

#include <stdio.h> int main(void) { printf("hello/n"); return 0; }

Construido deshabilitado:

$ gcc -fno-builtin -O1 -Wall builtin_printf.c && objdump -d -Mintel a.out 0000000000400530 <main>: 400530: 48 83 ec 08 sub rsp,0x8 400534: bf e0 05 40 00 mov edi,0x4005e0 400539: b8 00 00 00 00 mov eax,0x0 40053e: e8 cd fe ff ff call 400410 <printf@plt> 400543: b8 00 00 00 00 mov eax,0x0 400548: 48 83 c4 08 add rsp,0x8 40054c: c3 ret

Builtins habilitados:

gcc -O1 -Wall builtin_printf.c && objdump -d -Mintel a.out 0000000000400530 <main>: 400530: 48 83 ec 08 sub rsp,0x8 400534: bf e0 05 40 00 mov edi,0x4005e0 400539: e8 d2 fe ff ff call 400410 <puts@plt> 40053e: b8 00 00 00 00 mov eax,0x0 400543: 48 83 c4 08 add rsp,0x8 400547: c3 ret