2010-01-08 15 views
7

Tengo una pregunta sobre bibliotecas compartidas frente a bibliotecas estáticas cargando tiempo.Tiempo de carga para bibliotecas compartidas vs bibliotecas estáticas

Supongamos que tengo un ejecutable foo.exe que usa liba, libb, libc. También en un momento dado hay más de 10 instancias del ejecutable ejecutándose en la máquina.

Ahora si las 3 bibliotecas anteriores fueron bibliotecas compartidas: 1st Insance se carga en la memoria RAM: el tiempo necesario será el tiempo empleado por main() en foo.exe para cargar memoria (suponiendo que es insignificante) + tiempo para cargar liba + hora para cargar libb + hora para cargar libc Se inicia la segunda instancia: Ahora suponga que se ejecuta una segunda instancia de este ejecutable. Dado que todas las bibliotecas ya están cargadas en la memoria principal, el tiempo empleado es solo para cargar la memoria principal() en la memoria, que es insignificante.

Ahora bien, si los 3 bibliotecas anteriores fueron bibliotecas estáticas: primera insance se carga en RAM: El tiempo necesario será tiempo empleado por main() de foo.exe para ser cargado memoria (asumiendo su insignificante) + tiempo a load liba + time para cargar libb + time para cargar libc (Offcourse es ahora toda la parte del ejecutable como un todo) Se inició la segunda instancia: Ahora supongamos que se ejecuta una segunda instancia de este ejecutable. El tiempo tomado será nuevamente tiempo tomado por main() de foo.exe para cargar la memoria (asumiendo que es insignificante) + tiempo para cargar liba + tiempo para cargar libb + tiempo para cargar libc. (Dado que cada ejecutable no puede compartir liberies ya que estos son librareies estáticos)

Por lo tanto, mi conclusión es que con la biblioteca estática el tiempo de carga será mayor. Pero me dijeron que las bibliotecas compartidas tardan más tiempo durante la carga que las bibliotecas estáticas, por lo que habrá una demora, por lo que las bibliotecas compartidas no son una buena opción. Cómo es esto posible ?

Respuesta

9

Enlazar (resolver referencias) no es gratis. Con la vinculación estática, la resolución se realiza de una vez por todas cuando se genera el binario. Con la vinculación dinámica, tiene que hacerse cada vez que se carga el binario. Sin mencionar que el código compilado para ejecutarse en una biblioteca compartida puede ser menos eficiente que el código compilado para vincularse estáticamente. El costo exacto depende de la arquitectura y de la implementación del sistema de enlace dinámico.

El costo de hacer una biblioteca dinámica puede ser relativamente alto para el conjunto de instrucciones x86 de 32 bits: en el ELF binary format, uno de los registros ya escasos debe ser sacrificado para hacer que el código enlazado dinámicamente sea reubicable. El formato anterior a.out colocaba cada biblioteca compartida en un lugar fijo, pero no escalaba. Creo que Mac OS X ha tenido un sistema intermedio cuando las bibliotecas dinámicas se colocaron en ubicaciones predeterminadas en el espacio de direcciones, pero los conflictos se resolvieron a la escala de la computadora individual (la larga fase de "Optimización del rendimiento del sistema" después de instalar nuevas software). De alguna manera, este sistema (llamado pre-binding) le permite tener su pastel y comérselo también. No sé si todavía es necesario realizar un enlace previo ahora que Apple cambió prácticamente a la arquitectura amd64.

Además, en un sistema operativo moderno, tanto el código estáticamente como el vinculado dinámicamente solo se cargan (paginados) desde el disco si se usa, pero esto es bastante ortogonal a su pregunta.

+0

Muchas gracias por esta respuesta increíblemente rápida. Tenemos 2 escenarios arquitectónicos. He respondido mi pregunta como respuesta a mi pregunta. Por favor, búsquela abajo. – sud

2

Las bibliotecas estáticas se vinculan en tiempo compilado, las bibliotecas compartidas se vinculan en el tiempo de ejecución. Por lo tanto, los ejecutables que usan bibliotecas estáticas amortizan todo su tiempo de enlace incluso antes de escribirse en el disco.

+0

si hay 3 bibliotecas Liba, libB, libc todos son lib estática. Ahora dos ejecutables foo1.exe y foo2.exe que usan todas las 3 lib. 1. Si se ejecutan varias instancias de foo1.exe, compartirán las páginas de texto. Es esto correcto ? 2. Si foo1.exe y foo2.exe se ejecutan al mismo tiempo, no compartirán las páginas de texto. Es esto correcto ? Pls déjame saber – sud

+0

En el primer caso, las páginas de texto compartidas serán las de foo1 y no de las bibliotecas reales, ya que las bibliotecas ya no existen después de la vinculación estática. De lo contrario, ambos son correctos. –

0

Muchas gracias por esta respuesta increíblemente rápida. tenemos 2 arquitrabes arquitectónicos:

Q1.Architecure-1: Asume el tamaño del exe 3GB (bibliotecas estáticas). 95% son bibliotecas y 5% main(). Con un tamaño tan grande, la carga de este exe llevaría más tiempo (asumiendo bibliotecas estáticas) o la vinculación de este exe tomaría más tiempo (asumiendo el uso de bibliotecas compartidas, y si todas las bibliotecas ya están en memoria solo tiene que hacerse el enlace.)

Architecure-2: Supongamos que tengo un tamaño de exe 1.5GB (95% lib + 5% main()), y 6 instancias de esto se están ejecutando al mismo tiempo. Una vez que estas 6 instancias se terminen, se ejecutarán durante días, supongamos que estamos listos para tomar el retraso adicional durante la carga inicial + vinculación de estas 6 instancias.

Q2. Ahora bien, si estoy utilizando objetos compartidos en lugar de objetos estáticos, ¿tendré mucho espacio libre en la memoria RAM ya que todas las bibliotecas se comparten entre las 6 instancias? ¿No se acelerará mi ejecución en tiempo real debido a más espacio en la memoria RAM que disminuye el intercambio de páginas?

Q3. Si uso archivos 'map' para disminuir el número de símbolos exportados (lo cual solo es posible usando bibliotecas compartidas) ¿no disminuirá el tamaño de mi tabla de símbolos y no mejorará el rendimiento en el tiempo de ejecución?

Gracias Sud

+0

Si quiere decir ejecutar instancias del mismo programa ("foo.exe" en su pregunta original), el código se compartirá en la memoria (con todas las ventajas) con la versión enlazada estáticamente igual que con la vinculada dinámicamente. –

+0

Solo si se refirió a programas ligeramente diferentes foo1.exe, foo2.exe cada uno utilizando la misma liba, libb, lic ¿habría una ventaja para la vinculación dinámica. En este caso, solo permitiría compartir algo que no podría compartirse con enlaces estáticos. –

+0

En realidad, quise decir que el mismo ejecutable foo.exe (usando lib estática) tiene 6 instancias en lugar de foo1, foo2. Pero en este caso, ¿cómo se compartirá el código en la memoria? ¿No tendría cada instancia su propia copia en la RAM? Pensé que solo con bibliotecas compartidas se compartiría, no con lib estática. ¿Puedes proporcionar una URL que podría iluminarme? – sud

Cuestiones relacionadas