If Abfrage und Platzhalter
-
Betriebsstufe1 = 0 | Stufe = "Anlage aus" oder
Betriebsstufe1 = 375 bis 385 | Stufe = "Anlage Stufe1" oder
Betriebsstufe2 = 590 bis 610 | Stufe = "Anlage Stufe2" oder
Betriebsstufe2 = 676 bis 686 | Stufe = "Anlage Stufe3"int val = 300; int stage; if(val >= 590){ if(val >= 676) stage = 3; else stage = 2; }else{ if(val >= 375) stage = 1; else stage = 0; }
so muß das aussehen
-
no_code schrieb:
if(val >= 590){ if(val >= 676) stage = 3; else stage = 2; }else{ if(val >= 375) stage = 1; else stage = 0; }
so muß das aussehen
Was manche Leute für Ansprüche haben... :p
stage = (val >= 375) + (val >= 590) + (val >= 676);
Etwa 90% weniger Code und bei mir 15% schneller.
-
Nexus schrieb:
stage = (val >= 375) + (val >= 590) + (val >= 676);
Etwa 90% weniger Code und bei mir 15% schneller.
wow so hab ich das ja noch nie verwendet
-
Nexus schrieb:
no_code schrieb:
if(val >= 590){ if(val >= 676) stage = 3; else stage = 2; }else{ if(val >= 375) stage = 1; else stage = 0; }
so muß das aussehen
Was manche Leute für Ansprüche haben... :p
stage = (val >= 375) + (val >= 590) + (val >= 676);
Etwa 90% weniger Code und bei mir 15% schneller.
Wäre nicht
if(val>=676) stage=3; else if(val>=590) stage=2; else if(val>=375) stage=1; else stage=0;
schneller? Bei Dir müssen immer 3 Bedingungen getestet werden. Bei mir mir je nachdem bis zu 3.
Wobei no_code sogar optimiert hat auf die Garantie, daß nur zwei Bedingungen getestet werden.
Warum ist Dein Code schneller? Gibt es am Ende einen Prozessorbefehl, der genau dein Konstrukt unterstützt, zum Beisipiel den Wahrheitswert einer geprüften Bedingung als 0 oder 1 in ein Register schubst?
Welcher Wertebereich ist zum Messen sinnvoll? Ich nehme an so zwischen 0 und 1000.
-
volkard schrieb:
Welcher Wertebereich ist zum Messen sinnvoll? Ich nehme an so zwischen 0 und 1000.
Du denkst doch nicht etwa an eine Lookup-Tabelle?
-
Tim schrieb:
volkard schrieb:
Welcher Wertebereich ist zum Messen sinnvoll? Ich nehme an so zwischen 0 und 1000.
Du denkst doch nicht etwa an eine Lookup-Tabelle?
würd ja fast behaupten das eine so große lookuptable das eher langsamer machen würde...
-
Wobei ihr alle vergesst, dass der Threadersteller etwas ganz anderes will. Die Anforderungen sind zwar total wirr (so wirr, dass ich es zuerst für einen Programmierfehler hielt, obwohl es richtig war), aber sie sind anders.
-
SeppJ schrieb:
Die Anforderungen sind zwar total wirr (so wirr, dass ich es zuerst für einen Programmierfehler hielt, obwohl es richtig war), aber sie sind anders.
die müssen dann eben an das programm angepasst werden :p
-
no_code schrieb:
würd ja fast behaupten das eine so große lookuptable das eher langsamer machen würde...
Wiso das denn? Wenn die Tabelle auf dem Heap liegt und man sie einmal initialisiert hat, dürfte das doch schnell sein. Wird die Tabelle dann oft benutzt, rentiert sich das wieder. Und es reichen ja auch 1 Byte pro Element. Mit 1 kByte ist die Tabelle dann auch nicht allzu groß
-
Hi
Mit 1 Byte pro Element, ist es nicht so effizient wie eine Variable mit 32Bit, jenachdem was du für ein Prozessor hast bzw. OS.
lowbyte
-
FKF schrieb:
Die Varieble "var_array[6]" kann einen Wert aus den vier Bereichen besitzen.
und wenn der wert außerhalb der bereiche ist(390, 620, 690, etc), liefern die meisten 'optimierten' lösungen falsche ergebnisse. der einzige,zuverlässige ansatz ist von SeppJ
mfg
-
volkard schrieb:
Warum ist Dein Code schneller? Gibt es am Ende einen Prozessorbefehl, der genau dein Konstrukt unterstützt, zum Beisipiel den Wahrheitswert einer geprüften Bedingung als 0 oder 1 in ein Register schubst?
setge
tut das für>=
. Aber weshalb ist das eine spezielle Instruktion? Wahrscheinlich liegt ein Teil des Geschwindigkeitsschubs an den wegfallenden (vielleicht teilweise falsch vorhergesagten) Sprüngen fürs If. Assembler-Codes unter Microsoft Visual Studio 2008 Professional, kompiliert wurde mit /O2 (auf Geschwindigkeit optimieren) im Release-Modus:; volkard (4 Sprünge) 013D1120 cmp eax,2A4h 013D1125 jl MeasureVolkard+2Eh (13D112Eh) 013D1127 mov ecx,3 013D112C jmp MeasureVolkard+46h (13D1146h) 013D112E cmp eax,24Eh 013D1133 jl MeasureVolkard+3Ch (13D113Ch) 013D1135 mov ecx,2 013D113A jmp MeasureVolkard+46h (13D1146h) 013D113C xor ecx,ecx 013D113E cmp eax,177h 013D1143 setge cl 013D1146 mov dword ptr [esp+eax*4],ecx 013D1149 inc eax 013D114A cmp eax,3E8h 013D114F jb MeasureVolkard+20h (13D1120h)
; Nexus (0 Sprünge) 013D10A0 xor ecx,ecx 013D10A2 cmp eax,2A4h 013D10A7 setge cl 013D10AA xor edx,edx 013D10AC cmp eax,24Eh 013D10B1 setge dl 013D10B4 add ecx,edx 013D10B6 xor edx,edx 013D10B8 cmp eax,177h 013D10BD setge dl 013D10C0 inc eax 013D10C1 add ecx,edx 013D10C3 mov dword ptr [esp+eax*4-4],ecx 013D10C7 cmp eax,3E8h 013D10CC jb MeasureNexus+20h (13D10A0h)
; no_code (2 Sprünge) 013D1020 xor ecx,ecx 013D1022 cmp eax,24Eh 013D1027 jl MeasureNocode+36h (13D1036h) 013D1029 cmp eax,2A4h 013D102E setge cl 013D1031 add ecx,2 013D1034 jmp MeasureNocode+3Eh (13D103Eh) 013D1036 cmp eax,177h 013D103B setge cl 013D103E mov dword ptr [esp+eax*4],ecx 013D1041 inc eax 013D1042 cmp eax,3E8h 013D1047 jb MeasureNocode+20h (13D1020h)
volkard schrieb:
Welcher Wertebereich ist zum Messen sinnvoll? Ich nehme an so zwischen 0 und 1000.
Hab ich jetzt auch genommen. Ich hatte gestern wohl einen zu grossen Wertebereich, jetzt ist der Unterschied zwischen no_code und mir weniger deutlich. Dafür ist dein Code relativ langsam. Ausgabe (die Ergebnisse sind immer etwa in der Grössenordnung):
nocode: 0.311074 nexus: 0.286751 volkard: 0.435285 nocode: 0.294478 nexus: 0.27204 volkard: 0.417075 nocode: 0.304381 nexus: 0.274707 volkard: 0.40705
Mit AMD CodeAnalyst die Timer Samples für den Aufruf der
Nexus()
/Nocode()
/Volkard()
-Funktion gemessen, wobei diese etwas stärker gestreut sind:buf[i] = Nocode(i); // 27.34 | 30.02 | 26.11 buf[i] = Nexus(i); // 24.69 | 22.30 | 27.08 buf[i] = Volkard(i); // 44.35 | 44.24 | 44.03
Ich hoffe, mir sind keine groben Messfehler unterlaufen. Ich habs in C++ (nicht C) gemessen, im Folgenden der Code.
StopWatch
ist eine Stoppuhr-Klasse; die Arrays habe ich hingeschreiben, um Wegoptimierung zu verhindern; zudem habe ich das Inlinen einzelner Funktionen erzwungen. Eine Vertauschung der Aufrufe hat zu den selben Ergebnissen geführt.__forceinline int Nocode(int val) { int stage; if(val >= 590){ if(val >= 676) stage = 3; else stage = 2; }else{ if(val >= 375) stage = 1; else stage = 0; } return stage; } __forceinline int Nexus(int val) { int stage; stage = (val >= 375) + (val >= 590) + (val >= 676); return stage; } __forceinline int Volkard(int val) { int stage; if(val>=676) stage=3; else if(val>=590) stage=2; else if(val>=375) stage=1; else stage=0; return stage; } const size_t innerCount = 1000; const size_t outerCount = 80000; int MeasureNocode(StopWatch& s) { int buf[innerCount]; s.Start(); for (int i = 0; i < innerCount; ++i) { buf[i] = Nocode(i); } s.Stop(); return buf[rand() % innerCount]; } int MeasureNexus(StopWatch& s) { int buf[innerCount]; s.Start(); for (int i = 0; i < innerCount; ++i) { buf[i] = Nexus(i); } s.Stop(); return buf[rand() % innerCount]; } int MeasureVolkard(StopWatch& s) { int buf[innerCount]; s.Start(); for (int i = 0; i < innerCount; ++i) { buf[i] = Volkard(i); } s.Stop(); return buf[rand() % innerCount]; } int main() { StopWatch nocode, nexus, volkard; int buf[outerCount]; for (int i = 0; i < outerCount; ++i) { int vol = MeasureVolkard(volkard); int nex = MeasureNexus(nexus); int noc = MeasureNocode(nocode); buf[i] = nex + noc + vol; } std::cout << "\n\n"; std::cout << "nocode: " << nocode.GetElapsedTime() << std::endl; std::cout << "nexus: " << nexus.GetElapsedTime() << std::endl; std::cout << "volkard: " << volkard.GetElapsedTime() << std::endl; std::cout << "\n\n"; std::cout << buf[rand() % outerCount]; }
-
Dank euch allen.
Ich werde wohl SeppJ einen Vorschlag nehmen.
Denn die anderen sind für mich ganz Fremd.Gruß
Michael
-
[at] Nexus cool vielen dank für deine mühe. finde das ganz super mal so schön die unterschiede zu sehen. was doch diese kleinen dinge schon ausmachen können.
B.B. schrieb:
FKF schrieb:
Die Varieble "var_array[6]" kann einen Wert aus den vier Bereichen besitzen.
und wenn der wert außerhalb der bereiche ist(390, 620, 690, etc), liefern die meisten 'optimierten' lösungen falsche ergebnisse. der einzige,zuverlässige ansatz ist von SeppJ
mfg
so_schauts_aus schrieb:
SeppJ schrieb:
Die Anforderungen sind zwar total wirr (so wirr, dass ich es zuerst für einen Programmierfehler hielt, obwohl es richtig war), aber sie sind anders.
die müssen dann eben an das programm angepasst werden :p
-
no_c0de schrieb:
so_schauts_aus schrieb:
SeppJ schrieb:
Die Anforderungen sind zwar total wirr (so wirr, dass ich es zuerst für einen Programmierfehler hielt, obwohl es richtig war), aber sie sind anders.
die müssen dann eben an das programm angepasst werden :p
selten son schwachsinn gelesen