If Abfrage und Platzhalter



  • 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...


  • Mod

    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 🙄


Anmelden zum Antworten