Sollte man Optimierung für bestimmte seltene Fälle einbauen?
-
SideWinder schrieb:
Warum nicht einfach ein Template und das für diese drei Fälle spezialisieren. Da kann man nichts im Projekt zerstören und hat maximale Performance?!
MfG SideWinder
weil templates fuer statische dinge sind, wenn der template parameter bekannt ist, kannst du auch einfach eine konstante zuweisen. ich glaube es geht darum zur laufzeit anhand von variablen parametern zu entscheiden wie vorzugehen ist.
-
volkard schrieb:
raps schrieb:
von daher sehe ich das problem von 'zu spaet' nicht wirklich.
aber du kannst dir schon vorstellen, daß man software so baut, daß man von anfang an überhaupt keinen wert auf performance legt und man am ende sehr unzufrieden ist und daß man dann doch optimiert und beim optimieren das tolle design total zerstört und das gibt dann häßliche unwartbare frickelsoftware.
klar, wenn man etwas optimiert, wird der code meistens 'weniger schoen', deswegen sollte man das auch am ende machen. dann wird naemlich 99% vom code generisch und einfach lesbar bleiben, waehrend der kritische vermutlich uglyfied wird fuer die performance.
das problem ist, wenn man ueberall optimierungen blind einbaut (blind weil man garnicht gemessen hat, ob und was es bringt), dann weiss man nicht, ob man nicht sogar kontraproduktiv war, weil selbst die logischte theoretische annahme in der praxis das gegenteil bewirken kann. dafuer hat man aber ueberall schlechter zu lesenen code.
damit sage ich nicht, dass diese eine abfrage in diesem fall hier dramatisch ist, aber man sollte den leuten die sich soeine frage stellen muessen beibringen keine premature optimizations zu machen.gestern beim optimieren hab ich folgenden lustigen code geschrieben
//#define V_OrOdd(X,Y) si_or(X,Y) #define V_OrOdd(X,Y) si_shufb(Y,Y,*reinterpret_cast<qword*>(&reinterpret_cast<uint8*>(qOrSelect)[si_to_int(si_rotqbii(si_gb(X),4))]))
damit hab ich auf einer SPU ein OR auf der odd pipe simuliert, der standartbefehl laeuft auf der even pipeline. dadurch dass ich die even pipeline 100% ausnutze und nur 10% der odd, konnte ich laut statischem code analyser den load besser verteilen. hab 16 OR gespart und nun eine 100:70 auslastung (effektiv also 16cycles im inner loop schneller).
feierabend, oder?
beim profilen war dann dieser schnellere code langsammer, der simulator hat dann ergeben, dass die 1kb mehr code und das lesen von qOrSelect zwar wirklich schneller sind, aber dadurch den DMA-transfer mehr blockieren der parallel ablaeuft und deswegen die gesammtperformance weniger ist.den grossteil meiner arbeit optimiere ich, und ich weiss dass ich einem profiler mehr vertraue als mir
-
rapso schrieb:
#define V_OrOdd(X,Y) si_shufb(Y,Y,*reinterpret_cast<qword*>(&reinterpret_cast<uint8*>(qOrSelect)[si_to_int(si_rotqbii(si_gb(X),4))]))
damit hättest du 'ne gute chance bei einem obfuscated C contest. allein schon die benamung ist grossartig, si_rotqbii und so.
-
+fricky schrieb:
rapso schrieb:
#define V_OrOdd(X,Y) si_shufb(Y,Y,*reinterpret_cast<qword*>(&reinterpret_cast<uint8*>(qOrSelect)[si_to_int(si_rotqbii(si_gb(X),4))]))
damit hättest du 'ne gute chance bei einem obfuscated C contest. allein schon die benamung ist grossartig, si_rotqbii und so.
hat mich auch ne zeit gekostet rauszufinden weshalb er bei si_rotqbi den immediate nicht will, bis ich rausfand dass es si_rotqbi und si_rotqbii gibt *hehe*.
ist aber standard spu assemlber (bzw die instrinsics die lediglich si_ davor haben), siehe http://www.scribd.com/doc/2978344/SPU-Instruction-Cheat-Sheet-Insomniac-Games
-
rapso schrieb:
klar, wenn man etwas optimiert, wird der code meistens 'weniger schoen', deswegen sollte man das auch am ende machen. dann wird naemlich 99% vom code generisch und einfach lesbar bleiben, waehrend der kritische vermutlich uglyfied wird fuer die performance.
nicht nur das. wenn du's zu weit treibst, handelste dir abhängigkeiten ein, so dass deine optimierungen mit der nächsten prozessorgeneration, irgeneiner unscheinbaren hardwareänderung oder mit 'nem compiler-update, alle nicht mehr da sind.
rapso schrieb:
hat mich auch ne zeit gekostet rauszufinden weshalb er bei si_rotqbi den immediate nicht will, bis ich rausfand dass es si_rotqbi und si_rotqbii gibt *hehe*.
ist aber standard spu assemlber (bzw die instrinsics die lediglich si_ davor haben)ja, ich finds ja auch doof dass prozessorenhersteller den befehlen keine sprechenden namen geben, sondern auf bis zur unkenntlichkeit verstümmelte kürzel stehen.
-
+fricky schrieb:
ja, ich finds ja auch doof dass prozessorenhersteller den befehlen keine sprechenden namen geben, sondern auf bis zur unkenntlichkeit verstümmelte kürzel stehen.
ah, naja, sobald man sich dran gewoehnt hat, ist es schoen. der spu assembler folgt wenigstens einer konsistenten namenskonvention, sodass man sich viele befehle denken kann.
an sich ist spu assembler der schoenste den ich bisher sah, alles ist grundsaetzlich vektorisiert und viele dinge gibt es entweder in einen befehl (z.b. static_cast<int>(clamp(v,0.f,1.f)*INT_RANGE) was sonst 4 bis 8 instruktionen waere, ist si_cfltu) oder es gibt befehle die auf die beiden pipelines verteilt werden koennen, z.b. fuer reciproc hast du einen estimate auf der odd pipeline und interpolate (naehrung) auf der even pipeline, womit du effektiv nur 7cycles auskommst fuer 4gleichzeitig.
-
volkard schrieb:
aber du kannst dir schon vorstellen, daß man software so baut, daß man von anfang an überhaupt keinen wert auf performance legt und man am ende sehr unzufrieden ist und daß man dann doch optimiert und beim optimieren das tolle design total zerstört und das gibt dann häßliche unwartbare frickelsoftware.
Es gibt etliche Punkte, an denen man sich von vorneherein bessere oder schlechtere Karten verschafft und die zu selten ins Bewußtsein der Programmierer gerückt zu sein scheinen, weil die normalerweise an einem schnellen PC sitzen, da fällt's lange nicht auf, wenn Rechenzeit sinnlos verbrunzt wird. Natürlich gibt es weitere Aspekte, aber ich möchte das nur exemplarisch anreißen.
1. Systemdesign nach Umgebung
In Anbetracht der Targetplattform(en) muß eine grundlegende Strategie unter Berücksichtigung auch der Performance gefunden werden. Also, wenn ich eine API bedienen muß, die Hyperthreading anbietet, suche ich nach parallelisierbaren oder gänzlich unabhängigen Jobs, was sich als Ansatz eher verbietet, wenn einem ein nackter 8-Bit µC als Target ohne OS und Framework unterkommt. Wahrscheinlich werde ich auf dem PC nicht die optimale Strategie für den Ansatz finden, da ich eher auf den kleinen Kisten unterwegs bin; umgedreht bekomme ich immer wieder "gestückeltes" Polling zu sehen, das nur dann funktioniert, wenn die Plattform schnell im Vergleich zur Aufgabe ist. Haarsträubendes Zeug, das auch nur jemand einfallen kann, der glaubt, daß unter 16 Bit getrommelt werden muß.2. Summe der kleinen Sünden
Immer wieder nervend sind die Sachen, bei denen Mehrfachberechnungen immer des Gleichen angestoßen werden, weil Leute statt Zwischenergebnisse zu verwenden zweimal das Gleiche hinpinseln, frei nach dem Motto "soll sich der Compiler doch drum kümmern". Also z.B. e1 = a/b*c mit e2 = a/b*d. In der Tat, ein paar erkennen das und führen a/b nur einmal aus, aber bei einem for (i = 0; i <= strlen(searchstring); i++) kann auch der beste Optimierer nichts mehr machen. Auf dem PC fällt das erst ins Gewicht, wenn man wirklich große Datenmengen zu bearbeiten hat, ein Controller, der von 'ner Solarzelle, einem Goldcap und einem Uhrenquarz leben muß, kann sich so einen hirnlosen Luxus nicht leisten - Profiler gibt's dort auch eher selten. Derlei Beispiele gibt es übrigens noch viele mehr, wie mit ein bisserl Hirn viel Rechnerei zu sparen ist.Beides muß im Vorfeld und bei der Erstellung präsent sein, um nicht in eine Performance- Falle zu tappen, hat aber eigentlich nichts mit Optimierung zu tun.
An Tims 0/1/-1 Beispiel sieht man deutlich, daß es was bringen kann, wenn z.B. ein Hardwaremultiplizierer fehlt. Die nötige Gegenfrage lautet, wie sehr die Vergleiche weh tun und führt uns zu der Antwort, daß wir keine Antwort darauf haben, solange wir die typische Betriebssituation nicht kennen. Und wenn man Denke auf etwas verschwendet, von dem man nicht weiß, ob es überhaupt was bringt, dann ist das der klassische Fall von "premature optimization".
Ein sauberes Systemdesign und das "Performancekeeper- Bing" im Hinterkopf sind wichtiger, als sich im Vorfeld über sowas einen Kopf zu machen.