1) se basa en el hecho de que llamar a una función DLL siempre está utilizando un salto indirecto adicional. Hoy, esto suele ser insignificante. Dentro de la DLL hay algo más de sobrecarga en las CPU i386, porque no pueden generar código independiente de la posición. En amd64, los saltos pueden ser relativos al contador del programa, por lo que esta es una gran mejora.
2) Esto es correcto. Con las optimizaciones guiadas por la creación de perfiles, generalmente puede obtener un rendimiento de aproximadamente 10-15 por ciento. Ahora que la velocidad de la CPU ha alcanzado sus límites, puede valer la pena hacerlo.
Yo agregaría: (3) el enlazador puede organizar las funciones en una agrupación más eficiente de caché, de modo que se minimizan las costosas pérdidas de nivel de caché. También podría afectar especialmente el tiempo de inicio de las aplicaciones (según los resultados que he visto con el compilador Sun C ++)
Y no olvide que con las DLL no se puede eliminar el código muerto. Dependiendo del idioma, el código DLL podría no ser óptimo tampoco. Las funciones virtuales siempre son virtuales porque el compilador no sabe si un cliente lo sobrescribe.
Por estas razones, en caso de que no haya una necesidad real de archivos DLL, simplemente use la compilación estática.
EDITAR (para responder el comentario, por usuario subrayado)
Aquí hay un buen recurso sobre el problema de código de posición independiente http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
Como se explicó, x86 no los tiene AFAIK para nada más que rangos de salto de 15 bits y no para saltos y llamadas incondicionales. Es por eso que las funciones (de los generadores) que tienen más de 32K siempre han sido un problema y necesitaban trampolines integrados.
Pero en sistemas operativos x86 populares como Linux, no necesita preocuparse si el archivo .so / DLL no se genera con el gcc
conmutador -fpic
(que impone el uso de las tablas de salto indirectas). Porque si no lo hace, el código solo se arregla como un enlazador normal lo reubicaría. Pero al hacerlo, hace que el segmento de código no se pueda compartir y necesitaría una asignación completa del código del disco a la memoria y tocarlo todo antes de que pueda usarse (vaciar la mayoría de las cachés, presionar TLB), etc. Hubo un tiempo cuando esto se consideró lento.
Entonces ya no tendría ningún beneficio.
No recuerdo qué sistema operativo (Solaris o FreeBSD) me dio problemas con mi sistema de construcción de Unix porque simplemente no estaba haciendo esto y se preguntó por qué se estrelló hasta que me presenté -fPIC
a gcc
.