Ist es möglich, die Optimierung der Verbindungszeit zu aktivieren, während nur das strikte Aliasing für einige Funktionen deaktiviert wird?

8

Mein Programm entspricht der strengen Aliasing-Regel, mit Ausnahme einer Stelle: einer Kompilierungseinheit, die Hash-Funktionen wie MurmurHash3, SpookyHash usw. enthält. Auf x86 und x86_64 akzeptieren diese Hashing-Funktionen const char * , werfen sie auf uint32 und verarbeitet Daten in Blöcken von 4 Bytes. Dies macht sie viel schneller im Vergleich zur Verarbeitung von Daten Byte für Byte, aber ich glaube, dass dies die strenge Aliasing-Regel bricht. Im Moment kompiliere ich diese Kompilierungseinheit mit -fno-strict-aliasing, während ich den Rest des Programms mit -fstrict-aliasing kompiliere.

Aber ich frage mich, was passiert, wenn ich die Link-Zeit-Optimierung aktiviere. Soweit ich weiß, implementieren GCC und Clang Link-Zeit-Optimierungs-Sortierung, indem die Programmquelle in .o-Dateien gespeichert wird, so dass der Compiler bei der Verknüpfungsphase den Quellcode des gesamten Programms kennt. Ist es dann immer noch möglich, striktes Aliasing nur für die Hashfunktionen zu deaktivieren? Oder muss ich jetzt das strikte Aliasing für das gesamte Programm deaktivieren? Oder habe ich die Dinge komplett falsch verstanden, und MurmurHash3 / SpookyHash sind in der Tat strenge Aliasing-konform?

    
Hongli 10.09.2014, 11:45
quelle

3 Antworten

6
  

Im Moment kompiliere ich diese Kompilierungseinheit mit -fno-strict-aliasing, während ich den Rest des Programms mit -fstrict-aliasing kompiliere.

Sie können das Gleiche mit Optimierungen der Verbindungszeit tun. Kompilieren Sie nicht den spezifischen Objektcode mit Optimierungen der Verknüpfungszeit.

Beispiel mit clang (gleich mit gcc ):

%Vor%     
ouah 10.09.2014 12:20
quelle
6

Es gibt drei Dinge zu beachten:

  • Leistung
  • Portabilität
  • Standardkonformität

Sie erhalten die beste Leistung, wenn Sie das Kopieren von Daten vermeiden und einen ausgerichteten Zugriff gewährleisten können.

Nicht ausgerichteter Zugriff und Aliasing sind Probleme mit der Portabilität. Wenn Sie sich dazu entschließen, die Daten zu kopieren, wird dies für beides sorgen. Andernfalls müssen Sie den Algorithmus anpassen, um falsch ausgerichtete Eingabedaten zu verarbeiten, und sicherstellen, dass kein konkurrierender Zugriff über Zeiger des inkompatiblen Typs besteht:

Wenn Sie nur über einen einzelnen Zeigertyp auf Daten zugreifen, verstößt die Verletzung effektiver Schreibregeln Ihr Programm nicht konform, ist aber in der Praxis wahrscheinlich kein Problem, selbst wenn Sie -fno-strict-aliasing nicht übergeben - was genau ist Unit Tests zu haben, ist sehr praktisch.

Für SpookyHash habe ich eigentlich meine eigene C99-Version (die auch einen Off-by-One in V2 der Referenz behebt) Implementierung). Wenn es Ihnen gelingt, die effektive Typisierung zu verletzen und Ihre Architektur nicht ausgerichteten Zugriff unterstützt (oder alle Eingabedaten ausgerichtet sind), können Sie das Compilerflag -DSPOOKY_NOCOPY übergeben. Auf meinem x86-64-Rechner betrug die Leistungssteigerung je nach Eingangsgröße etwa 10-20%.

    
Christoph 10.09.2014 12:12
quelle
3

Es sollte möglich sein (zumindest könnten Sie es versuchen), da der letzte GCC funktionsspezifisch ist Optionspragmas . Sie könnten versuchen, etwas wie

hinzuzufügen %Vor%

vor deinen Alias-Funktionen und setze

%Vor%

nach ihnen.

Vielleicht müssen Sie diese mit

umschließen %Vor%

und natürlich einige #endif

Alternativ können Sie Builder-Tricks verwenden (zB autoconf , cmake oder eine ausgeklügelte GNU make 4.0-Regel, usw.), um Ihre eigene HAVE_GENUINE_GCC als 1 nur für das echte GCC Compiler und Ihr eigenes HAVE_GENUINE_CLANG als 1 für das echte Clang / LLVM Compiler, etc .... Oder vielleicht erkennen, dass die oben genannten Pragmas in einigen Beispielcode verstanden werden, und dann HAVE_WORKING_PRAGMA_GCC_OPTIMIZE als 1 definieren.

BTW, zumindest in GCC, -flto ist nicht speichert in Objektdateien eine Repräsentation der Programmquelle, sondern nur eine verdaute Form einiger interner GCC-Repräsentationen (wie Gimple, etc ..). .) erhalten, wenn Sie Ihren Quellcode kompilieren. Das ist ganz anders!

PS. Ich habe es nicht versucht, also ist es vielleicht nicht so einfach.

    
Basile Starynkevitch 10.09.2014 11:53
quelle

Tags und Links