1) basiert auf der Tatsache, dass beim Aufrufen einer DLL-Funktion immer ein zusätzlicher indirekter Sprung verwendet wird. Heute ist dies normalerweise vernachlässigbar. Innerhalb der DLL gibt es etwas mehr Overhead auf i386-CPUs, da sie keinen positionsunabhängigen Code generieren können. Auf amd64 können Sprünge relativ zum Programmzähler sein, was eine enorme Verbesserung darstellt.
2) Das ist richtig. Mit Optimierungen, die sich an der Profilerstellung orientieren, können Sie normalerweise eine Leistung von 10 bis 15 Prozent erzielen. Jetzt, da die CPU-Geschwindigkeit an ihre Grenzen gestoßen ist, könnte es sich lohnen, dies zu tun.
Ich würde hinzufügen: (3) Der Linker kann Funktionen in einer cacheeffizienteren Gruppierung anordnen, so dass teure Fehlschläge auf Cache-Ebene minimiert werden. Dies kann sich auch besonders auf die Startzeit von Anwendungen auswirken (basierend auf den Ergebnissen, die ich mit dem Sun C ++ - Compiler gesehen habe).
Und vergessen Sie nicht, dass mit DLLs keine Eliminierung von totem Code durchgeführt werden kann. Je nach Sprache ist der DLL-Code möglicherweise auch nicht optimal. Virtuelle Funktionen sind immer virtuell, da der Compiler nicht weiß, ob ein Client sie überschreibt.
Wenn aus diesen Gründen keine DLLs wirklich benötigt werden, verwenden Sie einfach die statische Kompilierung.
BEARBEITEN (um den Kommentar zu beantworten, vom Benutzer unterstrichen)
Hier ist eine gute Ressource zum positionsunabhängigen Codeproblem http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
Wie bereits erläutert, verfügt x86 nicht über AFAIK für andere als 15-Bit-Sprungbereiche und nicht für bedingungslose Sprünge und Aufrufe. Aus diesem Grund waren Funktionen (von Generatoren) mit mehr als 32 KB schon immer ein Problem und benötigten eingebettete Trampoline.
Unter gängigen x86-Betriebssystemen wie Linux müssen Sie sich jedoch nicht darum kümmern, ob die .so / DLL-Datei nicht mit dem gcc
Switch generiert wird -fpic
(wodurch die Verwendung der indirekten Sprungtabellen erzwungen wird). Wenn Sie dies nicht tun, wird der Code einfach so repariert, wie ein normaler Linker ihn verschieben würde. Dabei wird das Codesegment jedoch nicht gemeinsam genutzt, und es muss eine vollständige Zuordnung des Codes von der Festplatte zum Speicher und Berühren des Codes vorgenommen werden, bevor er verwendet werden kann (Leeren der meisten Caches, Aufrufen von TLBs) usw. Es gab eine Zeit wenn dies als langsam angesehen wurde.
Sie hätten also keinen Nutzen mehr.
Ich kann mich nicht erinnern, welches Betriebssystem (Solaris oder FreeBSD) mir Probleme mit meinem Unix-Build-System bereitet hat, weil ich dies einfach nicht getan habe und mich gefragt habe, warum es abgestürzt ist, bis ich mich beworben -fPIC
habe gcc
.