Is it just me, or …

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Jörg »

Vielleicht sollte man aufhoeren, MS VC als DEN Compiler zu sehen ;) Selbst der betagte gcc 4.3.3 bekommt es gebacken.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4935
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Schrompf »

Och naja... VC++ mag nicht DER Compiler sein, aber solange Visual Studio DEN Debugger hat, wird es kaum eine Diskussion geben :-)

Ich verfolge die gelegentlich auftauchenden Diskussionen über Compilerqualitäten... und soweit ich das beurteilen kann, produziert der GCC wirklich den besseren Code, teilweise drastisch schneller. Das tut allerdings auch der Intel-Compiler. Der AMD-Compiler taucht aus mir unerfindlichen Gründen bislang in keiner Diskussion auf. Der VC-Compiler hat allerdings einen großen Vorteil: er kompiliert schneller. Nach meinen subjektiven Einschätzungen durchaus Faktor 3 bis 5 schneller als der GCC.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben:P.P.S. Was soll überhaupt das dämliche = dort? 128 > x hätte es doch auch getan. Vielleicht kapiert der compiler das sogar besser.
In dem Augenblick, in dem ich 128 hinschriebe, würden beide Operanden als signed short behandelt, weil 128 zu groß für char ist.
Jörg hat geschrieben:Vielleicht sollte man aufhoeren, MS VC als DEN Compiler zu sehen ;) Selbst der betagte gcc 4.3.3 bekommt es gebacken.
Ich habe vor ein paar Monaten mal versucht, auf GCC umzusteigen … und so viel besser als VC ist der auch nicht. Den ersten Bug hatte ich – kein Witz – in der ersten Programmzeile: GCC #defined __cplusplus einfach zu 1 statt zum Datum des Sprachstandards. Von da an ging es dann weiter mit __builtins, die nicht existieren obwohl das komplette Internet das Gegenteil behauptet, einer Standardbibliothek wo die Hälfte (so ziemlich alles mit wchar_t) noch nicht implementiert ist und endet dann mit dem herrlichen online-Support, der schlicht und einfach nicht existiert (darüber, ob sie __cplusplus nun endlich standardkonform machen, flamen sie seit sieben Jahren). Irgendwie ist es da bequemer, von Zeit zu Zeit das VC-Kompilat gegenzutesten und hier und da von Hand zu optimieren. Und was Schrompf sagt kommt auch noch dazu.

Nichtsdestotrotz benutze ich GCC einmal im Monat, um meinen Code zu parsen – fehlerhaften Template-Code oder nicht standardkonforme Syntaxkonstrukte findet er bedeutend häufiger als VC, das z.B. die Spezialisierung von Templates im class-Scope erlaubt. Wichtig insbesondere seit ich in VC nicht mehr die Language Extensions deaktivieren will, weil ich dann die C++0x-Features einbüßen würde.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Jörg »

So war's nicht gemeint, ging mir eher darum, dass man solche Dinge ja schnell mit einem "Zweitcompiler" beliebiger Wahl gegentesten kann. Wollte keinesfalls den Thread in einem Flamewar münden lassen. Und offensichtliche Unzulänglichkeiten sollte man natuerlich in einem Feature-Request formulieren, egal fuer welchen Compiler.
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Alles klar. Während der Stunde, die ich jetzt brauche um MinGW C++0x-tauglich zu machen, könnt ihr ja mal darüber nachdenken, warum VC ein Placement-new durch Move-Constructor mit einem nullptr-Check versieht:

Code: Alles auswählen

new (&Array[Index]) int(::std::move(Array[Index-1]));

xor         ebx, ebx
lea         eax,[edx+ecx*4]  
cmp         eax,ebx  
je          0F21260h
mov         edi,dword ptr [eax-4]  
mov         dword ptr [eax],edi
dec         ecx // 0F21260h
Kurz: Bevor die int verschoben wird, wird getestet, ob das Ziel nullptr ist. Falls das der Fall ist, wird die Bewegung einfach übersprungen (es dient also nicht dazu, einen Fehler zu melden oder so). Weder die Implementierung vom Placement-new noch von ::std::move tun irgendwas. Wo kommt dieser völlig überflüssige Check her und warum wird er nicht wegoptimiert? Das ist eine innere Schleife, raubt mir ein Register und macht mir die Funktion in der Summe zu lang, um geinlined zu werden.

Edit: Selbst, wenn ich per __assume(nullptr < &Array[Index]); direkt vor dem new den trust-me-on-this-one-Modus erzwinge – er testet weiter. Wtf?!?
Zuletzt geändert von Krishty am 13.06.2010, 20:34, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2131
Registriert: 25.02.2009, 13:37

Re: Is it just me, or …

Beitrag von Alexander Kornrumpf »

In dem Augenblick, in dem ich 128 hinschriebe, würden beide Operanden als signed short behandelt, weil 128 zu groß für char ist.
Was mich ehrlich gesagt in der These bestätigt, dass das ein bekloppter(das wäre zu zeigen) Randfall(das ist nun per Definition unstrittig) ist.

Mal ehrlich, wieviele real-life Situationen fallen dir ein, in denen der Programmierer zwar denkt: "Mensch, bloß keine 128 schreiben, das passt nicht in char", aber dann nicht auch denkt "Hmm, Moment mal, der Vergleich an sich ist ja sinnlos", und das selbst wegoptimiert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Meine derzeitige Real-Life-Situation ist ein Parser:

Code: Alles auswählen

bool IsNonControlASCII(char x) {
    return (0x20 <= x) && (0x7F >= x);
}
Du darfst den zweiten Vergleich dort nicht weglassen, weil die Existenz eines Vorzeichens in char implementation-defined ist. Der Compiler hingegen darf es schon, weil er im Gegensatz zu dir erkennen kann ob das Programmverhalten dadurch beeinträchtigt würde oder nicht.

Eine Mögliche Alternative wäre natürlich das explizite return (0x20 <= static_cast<signed char>(x));, da hast du Recht. Aber der Compiler soll ja gerade das optimieren, was ich nicht selber optimiere weil ich zu faul, schöngeistig oder dumm bin, darin liegt doch der Sinn eines Optimizers … und nachdem ich gestern gesehen habe, wie er eine Verzweigung aus Zuweisungen und bitweisen Manipulationen zu einem komplett sprungfreien Bithaufen optimiert hat, hätte ich sowas Einfaches eigentlich schon erwartet.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2131
Registriert: 25.02.2009, 13:37

Re: Is it just me, or …

Beitrag von Alexander Kornrumpf »

Point taken.

Allerdings hoffe ich auf den Tag wo ASCII an sich ein "bekloppter Randfall" wird. Es ist eine Zumutung wie oft man auch heute noch Encodingproblemen begegnet.
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Is it just me, or …

Beitrag von TGGC »

mea culpa. Bin wohl auf das gleiche wie Schromp reingefallen. f'`8k


Gruß, TGGC (der kostenlose DMC Download)
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben:Allerdings hoffe ich auf den Tag wo ASCII an sich ein "bekloppter Randfall" wird. Es ist eine Zumutung wie oft man auch heute noch Encodingproblemen begegnet.
Bevor sie den Zeichensatz reformieren, sollten sie sich endlich mal auf vernünftige Line-Endings einigen ;)

Zurück zu dem Movement-Bug: Der Fehler scheint immer mit Placement-new aufzutreten, Move-Semantics haben nichts damit zu tun. Interessanterweise testet auch GCC 4.3.3 – allerdings nicht (wie VC 2010) die Zieladresse, sondern die Quelladresse. Aber genau wie VC springt er im Fall eines Nullzeigers einfach über die Konstruktion hinweg – kein Error-Handling, nichts. Da es beide Compiler tun, glaube ich nicht unbedingt an einen Fehler.

Hat jemand eine Idee, warum nach Placement-new und vor der Konstruktion absichtlich auf nullptr getestet werden sollte?

Hier mal ein Test:

Code: Alles auswählen

struct NonTrivialType {
	int x;
	NonTrivialType() : x(0) { }
	NonTrivialType(NonTrivialType const & Ref) : x(Ref.x) { }
};

	…
	NonTrivialType * Array = new NonTrivialType[2];
	new (&Array[0]) NonTrivialType(Array[1]);
Die letzte Zeile kompiliert zu

Code: Alles auswählen

13F6E12DF  test        r11,r11
13F6E12E2  je          13F6E12EBh  
13F6E12E4  mov         eax,dword ptr [r11+4]
13F6E12E8  mov         dword ptr [r11],eax
13F6E12EB  …
statt zu

Code: Alles auswählen

13F6E12E4  mov         eax,dword ptr [r11+4]
13F6E12E8  mov         dword ptr [r11],eax
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Jörg »

Ich muss mich korrigieren, auch gcc testet das Ziel. Habe mit den Array-Indizees gespielt und bin durcheinander gekommen. placement-new muss wohl garantieren, auch im 0-Fall keine Exception zu werfen....ist natuerlich aergerlich, wenn man diesen per-se ausschliessen kann.
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Okay, Update:

Der C++-Standard sagt: Ist new mit throw() deklariert (wirft also keine Exceptions) und gibt nullptr zurück, darf keine Initialisierung stattfinden. Das gilt auch für das throw()-deklarierte Placement-new – dort liegt wahrscheinlich der Ursprung des Tests. Soweit, so gut.

Problematisch ist allerdings, dass der Compiler den Test nicht wegoptimiert, wenn die Adresse des Placements definitiv nicht nullptr ist … und das im Fall von VC sogar, wenn man es per __assume() zu erzwingen versucht. Das ist ein Bug im Optimizer.

Für GCC gibt es bereits einen entsprechenden Bug-Report, der 2005 gefiled wurde und immernoch offen ist. Für VC habe ich ihn gerade abgeschickt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

VCs Optimizer arbeitet auch ganz toll, wenn man eine float als int reinterpretieren möchte. Falls ihr mal so eine Funktion schreibt: Übergebt nicht float, sondern float const & – sonst wird die Gleitkommazahl aus einem SSE-Register auf den Stack geschoben, von dort zurück ins SSE-Register geladen, wieder zurück auf den Stack geschrieben, dann in ein Integer-Register geladen und erst dann weiterverarbeitet. Am besten pfeift ihr auch auf Aliasing und macht dann einfach return reinterpret_cast<int const &> – damit scheint der Compiler am besten zurecht zu kommen.

Übrigens sind Integer-Vergleiche locker 10 % schneller als Gleitkommavergleiche – wenn ihr also massiv auf Basis von Gleitkommazahlen brancht, konvertiert ihr Bitmuster zu Integers im Zweierkomplement und vergleicht die.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Jeden Tag was Neues, Adam …

Hier gejammert und wenig später reproduziert: Der Linker entfernt unreferenzierte Compile-Time-constant-Arrays mal so, mal so aus der Exe. In meinem Programm hat er sie nur wegoptimiert, wenn sie in Zeigern lagen; beim Reproduzieren für den Bug-Report hat er sie nur entfernt, wenn sie in Arrays lagen.

Man kann sich also scheinbar nicht darauf verlassen, dass alles unreferenzierte Zeug rausfliegt – und es auch nicht wirklich erzwingen. Sollte das mal zum Problem werden (bei wirklich großen Datenmengen), sollte man sich vielleicht überlegen, ob man nicht per Präprozessor steuert, von welchen Symbolen der Compiler überhaupt weiß.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Oder man checkt seinen Code mit so etwas wie Lint bzw. einem g++, der einem Warnungen für nicht referenzierte Symbole ausspuckt.

Gruß Kimmi
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Hmmm, interessantes Feature … kannst du mir genauer erklären, wie das funktioniert?

Was zum Beispiel passiert, wenn ich libpng einbinde um PNGs zu laden? Dann müsste doch ein Drittel der dortigen Symbole (nämlich die, die nur zum Schreiben da sind) als unreferenziert angezeigt werden … dann nochmal die Hälfte von zlib (alles, was nur zum Packen statt zum Entpacken da ist) inklusive endloser Listen von Lookup-Tables für Datenverarbeitung und Fehlernachrichten … und 90 % der Symbole der Laufzeitbibliothek sowieso?

Und, naja, wenn der Compiler (bzw. Linker) warnt, dass ein Symbol nicht genutzt wird, dann wird er ja auch in der Lage sein, es wegzulassen. Das bedeutet im Umkehrschluss, dass bei den Symbolen, die wegen dem Unvermögen des Compilers unnötig in der Executable landen, auch keine Warnung kommen würde.

Achja, noch was am Rande: Es scheint dem Optimizer auch einen Unterschied zu machen, ob meine Exception-Klasse einen Zuweisungsoperator hat oder nicht … Programmierung ist echt unberechenbar.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Paralleles Thema: Gibt es eine Möglichkeit, den vector constructor iterator wegzuoptimieren?

Ich habe ein fixed-size-Array ([100]) eines User-Typs, dessen K’tor nichts anderes macht, als drei Member-Pointer auf 0 zu setzen. Anstatt nun 3×4×100 Bytes zu nullen, wird der vector constructor iterator aufgerufen und ruft den Konstruktor 100 Mal indirekt auf … erscheint mir irgendwie suboptimal :/
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Is it just me, or …

Beitrag von TGGC »

Krishty hat geschrieben:Paralleles Thema: Gibt es eine Möglichkeit, den vector constructor iterator wegzuoptimieren?

Ich habe ein fixed-size-Array ([100]) eines User-Typs, dessen K’tor nichts anderes macht, als drei Member-Pointer auf 0 zu setzen. Anstatt nun 3×4×100 Bytes zu nullen, wird der vector constructor iterator aufgerufen und ruft den Konstruktor 100 Mal indirekt auf … erscheint mir irgendwie suboptimal :/
Konstruktor schreiben, der nichts macht und dann den den Speicherblock mit memset fuellen. f'`8k


Gruß, TGGC (der kostenlose DMC Download)
Alexander Kornrumpf
Moderator
Beiträge: 2131
Registriert: 25.02.2009, 13:37

Re: Is it just me, or …

Beitrag von Alexander Kornrumpf »

Krishty hat geschrieben: Und, naja, wenn der Compiler (bzw. Linker) warnt, dass ein Symbol nicht genutzt wird, dann wird er ja auch in der Lage sein, es wegzulassen. Das bedeutet im Umkehrschluss, dass bei den Symbolen, die wegen dem Unvermögen des Compilers unnötig in der Executable landen, auch keine Warnung kommen würde.
Ich weiß nicht ob Kimmi die "Symbol defined but never used" Warnung meinte aber ich habe die immer so verstanden, dass der Gedanke dahinter ist dass der Programmierer sich vermutlich etwas dabei gedacht hat das Symbol zu definieren und es somit wahrscheinlich ein Irrtum des Programmieres ist dieses dann nicht zu benutzen. Der Charakter der Warnung war für mich immer "Du hast vergessen das Symbol zu benutzen" und nicht "Du hast eine Definition zuviel".
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Teilweise kann es sogar unmöglich für den Compiler sein, nicht referenzierte Symbole wegzulassen: wenn über einen Header solche Dinge durch irgendwelche Kunstgriffe unbenutzte Symbole hinzukommen, die dann aber für andere Dlls wichtig sind. Und ja, das ist mir schon passiert :). Das setzt natürlich voraus, daß diese Symbole external linked sind. Bei Dlls hat das das selber ja in der Hand, bei Libs nur bedingt.
Mir ist es lieber, wenn der Compiler eine Warnung ausspuckt.

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Aramis »

Man sollte einfach nicht vergessen dass ein Optimizer nichts ist, auf dass man sich 100% verlassen kann. Wenn absolut keine unreferenzierten Symbole drin sein duerfen, gibt es immer noch den Praeprozessor.

Fuer die allermeisten User spielt zudem Geschwindigkeit eine groessere Rolle als Groesse, daher duerfte die Entwicklung des MS-Linkers auch daraufhin ausgelegt sein.
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

TGGC hat geschrieben:]Konstruktor schreiben, der nichts macht und dann den den Speicherblock mit memset fuellen.
Leider keine Option, da es kein PoD-Typ ist. Aber selbst, wenn ich es täte (ich habe es aus Verzweiflung gerade probiert) würde es nicht wegoptimiert – es würde in Schleife ein K’tor aufgerufen, der aus nichts als mov eax, ecx; ret bestünde.
Ich muss mich übrigens korrigieren, der Compiler benutzt den eh vector constructor iterator – und das wird auch der Knackpunkt sein: Ich vermute, dass der Compiler das tut, weil das Objekt unwindable ist (kein leerer Destruktor). Wahrscheinlich hat da irgendjemand angenommen, dass Objekte, sobald unwindable, auch ausnamesicher initialisiert werden müssen. Da der K’tor hier aber überhaupt keine Ausnahme auslösen kann (und der Compiler das auch korrekt erkennt, weil er an anderen Stellen entsprechenden Code weglässt) ist es hier auch überflüssig, ausnahmesicher zu initialisieren. Oder sehe ich das falsch?
Alexander Kornrumpf hat geschrieben:Ich weiß nicht ob Kimmi die "Symbol defined but never used" Warnung meinte aber ich habe die immer so verstanden, dass der Gedanke dahinter ist dass der Programmierer sich vermutlich etwas dabei gedacht hat das Symbol zu definieren und es somit wahrscheinlich ein Irrtum des Programmieres ist dieses dann nicht zu benutzen. Der Charakter der Warnung war für mich immer "Du hast vergessen das Symbol zu benutzen" und nicht "Du hast eine Definition zuviel".
Kann es sein, dass diese Warnung nur für den Quellcode der aktuellen Executable getriggert wird und nicht für alles, was zu ihr dazugelinkt wird?
kimmi hat geschrieben:Teilweise kann es sogar unmöglich für den Compiler sein, nicht referenzierte Symbole wegzulassen: wenn über einen Header solche Dinge durch irgendwelche Kunstgriffe unbenutzte Symbole hinzukommen, die dann aber für andere Dlls wichtig sind. Und ja, das ist mir schon passiert :). Das setzt natürlich voraus, daß diese Symbole external linked sind. Bei Dlls hat das das selber ja in der Hand, bei Libs nur bedingt.
Mir ist es lieber, wenn der Compiler eine Warnung ausspuckt.
Ja, eine Warnung wäre mir auch lieb, aber der Compiler hält einfach nur die Klappe und packt die Symbole (wahllos!) mit rein. Achja, was wären das für Kunstgriffe?
Aramis hat geschrieben:Man sollte einfach nicht vergessen dass ein Optimizer nichts ist, auf dass man sich 100% verlassen kann.
Wenn ich ihn geschrieben hätte, wäre das wohl anders. Aber vielleicht ändert es sich schon, wenn ich das Team weiterhin täglich mit Bug-Reports bombardiere … :)
Aramis hat geschrieben:Fuer die allermeisten User spielt zudem Geschwindigkeit eine groessere Rolle als Groesse, daher duerfte die Entwicklung des MS-Linkers auch daraufhin ausgelegt sein.
Es macht aber schon einen Unterschied, ob ein Linker einfach nur die Hälfte der Symbole weglässt, bei der er am schnellsten feststellen kann, dass sie unbenutzt sind oder ob er absolut gleichberechtigte Symbole ohne jedes nachvollziehbare Muster behält oder nicht. Das eine ist eine Optimierung, das andere imo ein Bug oder zumindest Nachlässigkeit.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Zum Beispiel einen Int als volatile markieren, damit eine Variable nicht wegoptimiert wird. Oder man zaubert sich mit dem Präprozessor Symbole weg / Dummysymbole hin, um Linkprobleme in den Griff zu kriegen ( für Dummy-Wrapper beliebt, link mal F77, F90, C und C++ Libs zusammen, da kommt Freude auf ). Und ich hatte erst letztens ein Problem mit einem auf dem Heap generierten Objekt, daß unresolved symbols Fehler erzeugt hatte. Auf dem Stack kreiert waren die weg ( flgl heißt die Lib ). Ich hab den Fehler aus Zeitmangel nicht nachvollzogen.

Und wenn ich beim 2008'er das Warninglevel auf 4 stelle, kriege ich zumindest in meinem Code Warnungen für definierte, aber nicht referenzierte Symbole.

Gruß Kimmi
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

kimmi hat geschrieben:Und wenn ich beim 2008'er das Warninglevel auf 4 stelle, kriege ich zumindest in meinem Code Warnungen für definierte, aber nicht referenzierte Symbole.
Wtf, ich kompiliere seit Jahren nur mit Warning Level 4. Ich bekomme Warnungen bei unreferenzierten Parametern, unreferenzierten lokalen Objekten – aber noch nie bei unreferenzierten Funktionen oder globalen Objekten. Jetzt muss ich aber mal einen Blick in die Compiler-Einstellungen werfen …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Ops, sorry! Die Warnungen über nicht referenzierte Funktionen kriege ich von Lint! Ich hab die durch den Tüddel bekommen!

Gruß Kimmi
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Ah, okay! Microsofts statische Code-Analyse schmeißt vergleichbare Warnungen leider nicht. Dafür habe ich jetzt das Warning-Level WAll entdeckt, boah, da geht jedem Pedanten das Herz auf.

Code: Alles auswählen

struct X {
    enum {
        A,
        B,
        NumValues,
    }; // warning C4820: 'X' : '3' bytes padding added after data member 'NumValues'
    int Members[NumValues];
};

Code: Alles auswählen

__assume(x <= 3); // warning C4557: '__assume' contains effect '='
Es hat wohl einen Grund, warum diese Warnungen per default ausgeblendet werden.

Edit: DA!
Warning | 3081 | warning C4514: '_chgsignl' : unreferenced inline function has been removed | X:\Tools\VS2010\VC\include\math.h | 380
und direkt wieder herp derp:

Code: Alles auswählen

__declspec(noinline) void Foo(); // warning C4514: 'Foo' : unreferenced inline function has been removed
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

Code: Alles auswählen

inline int Round(double const & Value) {
    return ::_mm_cvtsd_si32(::_mm_load_sd(&Value));
}
…
int x = Round(1.0);
=>

Code: Alles auswählen

movsd       xmm0,mmword ptr [__real@3ff0000000000000]  
movsd       mmword ptr [SomeLocalAddress],xmm0  
movsd       xmm1,mmword ptr [SomeLocalAddress]  
cvtsd2si    edx,xmm1  
War nicht genau das ein Grund, Intrinsics zu benutzen? (Übrigens ist das ein x64-Build; unter x86 ist der Code noch ineffizienter, weil Round() garnicht erst geinlined wird.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Wieso nimmst du da nicht einfach floor, der soll gemäß MS-Doku für alle Architekturen ein Intrinsic sein:

Code: Alles auswählen

inline long floor(double val )
{
  return (long)floor( val + 0.5 );
}
Das sieht dann auch etwas lesbarer aus und ist definitiv portabler. Keine Ahnung, was da an Assemblercode rausfällt. Außerdem gibst du einen int für einen Double zurück, wahrscheinlich für den absoluten Anteil des Doubles. Eventuell liegt da das Problem, weil double auf Int gecastet werden muß? Ich weiß nicht, wie das auf 64-Bit-Plattformen aussieht. KA!

Gruß Kimmi
Benutzeravatar
Krishty
Establishment
Beiträge: 8295
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Is it just me, or …

Beitrag von Krishty »

kimmi hat geschrieben:Wieso nimmst du da nicht einfach floor
Weil es nur für positive Zahlen funktioniert und um den Faktor 10 langsamer ist (floor ist zwar ein Intrinsic, aber nicht nur ein einziger Assembler-Befehl wie es cvtsd2si ist).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Is it just me, or …

Beitrag von kimmi »

Das mit dem Langsamer mag sein, aber floor gibt es für float und double. In Kombination mit dem ?-Operator und ceil klappts auch für negative :). Aber da bleibt natürlich das Performance-Problem.

Gruß Kimmi
Antworten