Sammelthread zu Visual C++’ Compiler

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Benutzeravatar
Krishty
Establishment
Beiträge: 7502
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Krishty »

Krishty hat geschrieben:
07.02.2021, 02:13
Hier ist der komplette Workaround:
Visual C++ kann die Funktion nicht statisch auflösen. Wenn man also bitsOf(123.0f) schreibt, dann lädt Visual C++ da nicht direkt die Hex-Konstante 0x42F60000 in ein Allzweckregister, sondern erzeugt eine float-Konstante 123.0f, lädt sie in ein xmm-Register, und überführt sie via MOVD in ein Allzweckregister. Also ein Speicherzugriff und zwei Befehle, wo eigentlich nix sein sollte.

constexpr bringt nichts, weil es für SSE-Intrinsics nicht zur Verfügung steht (Bug Report, den ich schon gepusht habe).

Wenn ich diese Grütze von Hand auflöse, ist mein powf() wieder acht Prozent schneller – ~37 Takte. (powf() muss prüfen, ob das Ergebnis überläuft, um vernünftig inf zurückzugeben. Das geschieht über Bitvergleiche mit Limits.)

Das Üble ist: Ich habe Millionen Artikel gelesen (und hier geteilt!), in denen so Dinge stehen, wie: Ein Ryzen schafft zwei L1-Speicherzugriffe pro Takt. Ein Ryzen führt spekulativ 120 Befehle im Voraus aus. CPUs haben seit 2003 keine Load-Hit-Store-Penalty. Man hat 30 Slots für die Sprungvorhersage, und konstante Sprünge sind kostenlos.

Und das scheint alles Bullshit zu sein. Man schmeißt einen unnötigen Load raus, der eigentlich perfekt gepipelinet und predicted sein sollte, und der Code wird schneller. Man schmeißt einen Sprung raus, der immer zu 100 % nicht genommen wurde (also das einfachste für die Sprungvorhersage überhaupt), und der Code wird schneller. Mit jedem einzelnen Speicherzugriff, den ich rauskicke, purzeln die Prozente, obwohl jedes Paper sagt, dass bis zu zwei pro Takt gratis wären.

tl;dr: constexpr bringt mit Intrinsics nichts, und deshalb schnappt ihr euch am besten einen Taschenrechner und rechnet alle Konstanten selber aus und hard-codet sie. Als wär’s 1983.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 7502
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Krishty »

Fun fact: Als ich zu dem Bug recherchiert habe, kam sofort „wie kann die CRT std::bit_cast implementieren, ohne dass memcpy() eine constexpr-Funktion ist“ :(
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 7502
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Krishty »

Der aktuelle Preview-Compiler hat begonnen, .reloc-Sections als Discardable zu markieren. Laut Raymond Chen sollte das Flag seit 30 Jahren keine Bedeutung mehr haben.

Entweder ist ihnen was aus dem /KERNEL-Modus durchgeglitcht, oder der Windows 10-Memory-Manager bekommt ein neues Feature.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 7502
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Krishty »

Visual C++ 2019 scheint im prä-C++20-Modus echte Probleme mit statisch initialisierten std::strings zu haben.

Wenn ihr irgendwo global schreibt

  std::string lol = "hallo welt";

dann erzeugt Visual C++ glatt 500 Bytes an Code und Daten. Um den Konstruktor von std::string aufzurufen. Fünf fucking hundert Bytes! WTF

  auto const lol = "hallo welt"; // 500 Bytes kleineres Kompilat PRO STRING

Fun fact: Kompiliertes Assimp besteht zu fast einem Prozent aus statisch initialisierten std::strings, mit denen später nichts anderes gemacht wird, als c_str() aufzurufen. Patches sind unterwegs.

Ich habe oben nicht über C++20 geschrieben, weil damit ja constexpr für den K’tor eingeführt wurde. Möglicherweise fällt der Code damit radikal besser aus. Aber wenn man nur einen C-String braucht, ist es immernoch das Beste, einfach einen C-String hinzuschreiben.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1404
Registriert: 26.02.2009, 10:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von kimmi »

Noch besteht Assimp Kompilat zu 1% aus statisch initialisierten std::strings, noch!
Benutzeravatar
Jonathan
Establishment
Beiträge: 1639
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Jonathan »

Wie, was? Warum sind std::strings in C++ so scheiße?
Ich bin seit langem dafür absolut immer std::string zu benutzen. Aus Robustheitsgründen. Ein Großteil aller Sicherheitslücken geht auf die mangelnde Speicherverwaltung von C zurück, ich weiß gar nicht, wie oft ich in Sicherheitsmeldungen schon das Wort Buffer-Overflow gelesen habe. Meine Hoffnung war immer, dass der Overhead bei sowas wie 5% liegt (aufs ganze Programm bezogen), was durch schneller werdende Prozessoren nach ein paar Monaten also komplett egal ist und es somit total unvernünftig sein sollte, die alten C-Varianten (auch für Arrays usw.) zu verwenden.

Irgendwo hab ich auch mal einen Artikel gelesen, dass in Chrome ständig zwischen C-String und std::string konvertiert wurde, teilweise wurden Variablen durch 20 Funktionen durchgereicht und dafür jedesmal umgewandelt. Das zu beheben hat wohl extrem viel gebracht. Das ist traurig, denn nach meinem Gefühl sollte es alle diese Probleme nicht geben. Was ich mit all dem sagen will, weiß ich grad auch nicht, ich glaube dieser Post ist eher ein Rumgejammer darüber, wie schlimm schon wieder alles ist.
Lieber dumm fragen, als dumm bleiben!
Benutzeravatar
Krishty
Establishment
Beiträge: 7502
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von Krishty »

Du meinst wohl https://groups.google.com/a/chromium.or ... Z5ZK0K3gEJ

Mit C++20 sollte dieser furchtbare Overhead für Konstanten verschwinden, aber irgendwie kann noch kein Compiler constexpr-Strings?! https://godbolt.org/z/5a9qo3Yaf

Ach ja, das Originalproblem illustriert: https://godbolt.org/z/7rx7e1P73 vs https://godbolt.org/z/oYxzra9Wq
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
DerAlbi
Establishment
Beiträge: 252
Registriert: 20.05.2011, 05:37

Re: Sammelthread zu Visual C++’ Compiler

Beitrag von DerAlbi »

Code: Alles auswählen

constexpr std::string_view foo("String")
und dann

Code: Alles auswählen

foo.data()
statt c_str().
Da haste alles Gedöns der STL falls nötig und die code-gen vom const char*
Antworten