1) baseia-se no fato de que chamar uma função DLL está sempre usando um salto indireto extra. Hoje, isso geralmente é insignificante. Dentro da DLL, há mais sobrecarga nas CPUs do i386, porque elas não podem gerar código independente de posição. No amd64, os saltos podem ser relativos ao contador do programa, portanto, isso é uma grande melhoria.
2) Isso está correto. Com otimizações guiadas por criação de perfil, geralmente você pode obter de 10 a 15% do desempenho. Agora que a velocidade da CPU atingiu seus limites, pode valer a pena fazê-lo.
Eu acrescentaria: (3) o vinculador pode organizar funções em um agrupamento mais eficiente em cache, de modo que as perdas caras no nível do cache sejam minimizadas. Também pode afetar especialmente o tempo de inicialização dos aplicativos (com base nos resultados que eu vi no compilador Sun C ++)
E não esqueça que, com as DLLs, nenhuma eliminação de código morto pode ser executada. Dependendo do idioma, o código DLL também pode não ser o ideal. As funções virtuais são sempre virtuais porque o compilador não sabe se um cliente está substituindo-o.
Por esses motivos, caso não haja necessidade real de DLLs, basta usar a compilação estática.
EDITAR (para responder ao comentário, por sublinhado do usuário)
Aqui está um bom recurso sobre o problema do código independente da posição http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
Como explicado, o x86 não os possui AFAIK para mais nada, então intervalos de salto de 15 bits e não para saltos e chamadas incondicionais. É por isso que funções (de geradores) com mais de 32K sempre foram um problema e precisavam de trampolins incorporados.
Porém, em sistemas operacionais x86 populares como o Linux, você não precisa se preocupar se o arquivo .so / DLL não for gerado com a gcc
opção -fpic
(o que reforça o uso das tabelas de salto indiretas). Porque se não o fizer, o código será corrigido apenas como um vinculador normal o realocaria. Mas, ao fazer isso, torna o segmento de código não compartilhável e precisaria de um mapeamento completo do código do disco para a memória e tocá-lo antes de poder ser usado (esvaziando a maioria dos caches, atingindo TLBs) etc. Houve um tempo quando isso foi considerado lento.
Então você não teria mais nenhum benefício.
Não me lembro o que OS (Solaris ou FreeBSD) me deu problemas com meu sistema de compilação Unix porque eu não estava fazendo isso e se perguntou por que ele caiu até que eu aplicada -fPIC
para gcc
.