Also … Update von Visual Studio 15.5.5 auf 15.6. Einige Programme werden größer.
Ursache scheinen zwei Änderungen in der CRT zu sein:
- Eine der Standardfunktionen nutzt nun Exception Handling (ich befürchte, eine von sin() cos() tan() exp() pow()). Also landet nun Exception Handling in meiner EXE.
Ich sehe folgende neue Symbole in meinen Modulen:- 192 B: __acrt_exception_action_table (exception_filter.obj)
- 132 B: __DestructExceptionObject (ehhelpers.obj)
- 64 B: _CallSettingFrame (handlers.obj)
- 24 B: __DestructExceptionObject$filt$0 (ehhelpers.obj)
- Die CRT bringt eine Funktion mit, um die Dekoration von Funktionsnamen zu entfernen (UnDecorator). Diese Funktion wurde umgeschrieben, so dass sie nun strncmp() nutzt (geraten – könnte auch das Exception Handling sein). Gelöscht:
- 8 B: UnDecorator::outputString (undname.obj)
- 4 B: UnDecorator::maxStringLength (undname.obj)
- 125 B: strncmp (strncmp.obj)
- 4 B: UnDecorator::m_CHPENameOffset (undname.obj)
- 4 B: UnDecorator::m_recursionLevel (undname.obj)
- Irgendwo wird eine Lookup-Tabelle __newctype benutzt (768 B).
Dummerweise finde ich die betreffende Datei ctype.c nicht in dem CRT-Quelltext, darum weiß ich nicht mehr drüber.
Das mit den Exceptions wäre vermeidbar gewesen, da bin ich mir sicher.
Weiter mit der Code Generation:
- optimize for speed: return ~0; erzeugt nun statt OR EAX, -1 (drei Bytes) MOV EAX, -1 (fünf Bytes).
- optimize for speed: Sprünge erzwingen nun häufiger glatte Adressen (viel mehr Padding).
15.5 (Schleifenanfang sieben Bytes vom Funktionsanfang):
49 FF C1 INC R9
15.6 (selbe Situation):
66 0F 1F 84 00 00 00 00 00 NOP WORD PTR[RAX+RAX]
49 FF C1 INC R9 - optimize for size: Mehrfache _mm_setzero_ps() werden nun zusammengefasst. Wenn in 15.5 zwei Funktionen einen Vektor via _mm_setzero_ps() genullt haben, landeten sehr oft auch zwei XORPS im Code. Ab 15.6 werden sie öfter zusammengefasst.
Das ist schwer zu entscheiden – meist möchte man tatsächlich doppelt nullen, um die Parallelität zu erhöhen. Wenn aber z.B. die Abhängigkeitsketten gleich lang sind, ist es sinnlos, zwei Register zu nullen. Ich vermute, dass sie was in diese Richtung verbessert haben.
Die Optimierung greift durchaus an 10, 20 Stellen in meinen Programmen und spart dort jeweils ein paar Bytes. Der Gewinn kommt eher nicht durch weniger XORPS-Befehle, sondern durch reduzierten Registerdruck (weniger Spilling auf den Stack).
Gut möglich, dass diese Optimierung auch bei Geschwindigkeitsoptimierung greift – dort wird sie aber wohl durch die anderen Änderungen verdrängt.
Ich messe hier zum ersten Mal, dass meine Programme durch ein Release minimal kleiner geworden sind. Schön. Aber eben nur, sofern man nicht die statische CRT linkt und von dem Kilobyte neuem Bloat getroffen wurde :(