@gregor



  • Hallo,

    wenn ich auf Release kompiliere, brauch er unterm BCB 6 immernoch 3465ms

    mfg
    v R

    PS: gcc kennt keine windows.h, daher faellt er wohl weg.



  • class TestClass 
    { 
        private int number; 
    
        public TestClass () 
        { 
        } 
    
        public TestClass (int i) 
        { 
        	number = i;
        } 
    
        public int getNumber () 
        { 
            return number; 
        } 
    
        public void setNumber (int i) 
        { 
            number = i; 
        } 
    }
    
    class Test
    {
    	public static void main(String[] args)
    	{ 
    		long time = System.currentTimeMillis();
    
     	   	int size = 500; 
      	  	int sum = 0; 
    
     	   	TestClass[] array = new TestClass[size]; 
     	   	int i,j; 
    
      	   	for (j = 0 ; j < 200000 ; ++j) 
     	   	{ 
     	       	for (i = 0 ; i < size ; ++i) 
        	    { 
            	    array[i] = new TestClass(i); 
            	} 
    
            	for (i = 0 ; i < size ; ++i) 
            	{ 
              	  	sum += array[i].getNumber (); 
             	} 
        	} 
    
        	System.gc();
    		System.out.println(System.currentTimeMillis() - time);
    	}
    

    Ich bin mir nicht sicher, ob das ne gleichwertige Übersetzung ist, braucht bei mir 4900ms.
    Und jetzt bau bitte noch ne Array-Indexprüfung ein. 😉

    EDIT: Der Unterschied zwischen Debug- (71s) und Release-Version (1,3s) ist gigantisch, dem trau ich nicht so ganz.



  • virtuell Realisticer schrieb:

    PS: gcc kennt keine windows.h, daher faellt er wohl weg.

    wird nur für VirtualAlloc/VirualFree gebraucht. hab leider keine ahnung, wie man sich unter linux ne speicherseite vom BS besorgen tut. muß leider direkt vom BS besorgen, damit die seite auf 4k aligned ist.



  • hat auch einer zugleich java und c++ drauf und kann beide zeiten ermitteln?



  • c++:
    2062

    java:
    7892
    24950000000



  • MSVC6 release: 1872
    java 1.4.2.1: 4977



  • volkard schrieb:

    virtuell Realisticer schrieb:

    PS: gcc kennt keine windows.h, daher faellt er wohl weg.

    wird nur für VirtualAlloc/VirualFree gebraucht. hab leider keine ahnung, wie man sich unter linux ne speicherseite vom BS besorgen tut. muß leider direkt vom BS besorgen, damit die seite auf 4k aligned ist.

    Hmmm...ich schau mal in meinen schlauen Buechern nach, is schon ne Zeit lang her,
    dass ich _so_ nah am BS programmiert hab :).

    mfg
    v R



  • So, ich hab das ganze jetzt ein ganz klein wenig fuer den gcc angepasst.

    Ich kann auf meinem System getrost malloc einsetzten, da die Standard-Pagesize
    auf meinem System 4096 ist. Zudem hab ich das Ganze so abgeaendert, dass man
    auf einem BSD-System die Konstante BSD definieren muss, damit 2 weitere
    Dateien includiert werden, der typedef des u32-Typs geaendert, sowie die
    VirtualAlloc/VirtualFree durch malloc/free geaendert werden. Bei malloc wird
    vom System garantiert, dass der Speicher zur Pagesize hin passend 'aligned'
    ist. Da die von dir festgelegte Pagesize genau der auf meinem System
    entspricht, gibt es da auch keine Probleme.

    Wenn dem nicht so ist, weiss ich auch nicht weiter. Auf BSD-Systemen gibt es,
    anscheinend, keine aequivalente Funktion zu VirtualAlloc. Auf Linux-Systemen
    kann man sich mittels kmalloc() und kfree() helfen, da man bei diesen
    Funktionen die Pagesizegroesse angeben kann.

    Naja, jedenfalls braucht das Programm jetzt noch 1313ms.

    mfg
    v R



  • Volkard's Code VC++ 7.1 1515ms
    Optimizer's Code Java 1.4.2 5344ms
    Gregor's Code Java 1.4.2 5813ms



  • Ich hab in den C++ Code noch ne Indexprüfung für den Array-Zugriff eingebaut, das macht aber keinen nennenswerten Unterschied (1270 -> 1500).
    Aber ohne den Test in Frage stellen zu wollen: Theoretisch kann die Zahlensumme berechnet werden, ohne die ganzen Objekte wirklich zu erzeugen und zu deleten. Wäre es möglich, dass der C++ Compiler das Ganze einfach rauskickt?

    Der Grund: Ich lass mir ja gerne erzählen, dass der Debug-Build 10- oder 20mal langsamer ist. Aber bei einem so trivialem Programm 50mal (!!) langsamer zu sein, kommt mir echt happig vor (etwa 70s Laufzeit).



  • @Optimizer: Initialisier die Summe doch einfach mal mit einem Zufallswert oder mit der aktuellen Zeit oder so und gib sie am Schluss aus. Das sollte doch eigentlich das Problem beheben, wenn es denn wirklich existiert.

    @virtuellRealisticer: Was willst du aussagen, wenn du die C++-Werte ohne die Java-Vergleichswerte angibst?

    Insgesamt sind die Ergebnisse der neuen C++-Version IMHO glaubhaft und recht gut. Trotzdem bin ich entsetzt, welchen Aufwand man treiben muss, um da entsprechende Performance herauszuholen. IMHO zeigt dieses Beispiel sehr eindrucksvoll, wie nützlich und mächtig ein automatisiertes Speichermanagement ist.



  • Das gleiche habe ich auch gedacht Gregor, wenn man will kann man mit C++ schneller
    sein, jedoch muss man dafür einigen Aufwand betreiben, man vergleiche einmal beide
    Programme.
    Aber D wird ja beides unterstützen, nen GC und wenn man will jederzeit das Management
    von Hand 🙂



  • Gregor schrieb:

    IMHO zeigt dieses Beispiel sehr eindrucksvoll, wie nützlich und mächtig ein automatisiertes Speichermanagement ist.

    Nein, zeigt es IMHO nicht. Denn dazu müsste Volkard jetzt noch einen GC coden, um auf den selben Stand zu kommen (den wir bei dem Java-Programm haben), damit man von automatisiertem Speichermanagement sprechen kann. 😉
    Das würde den Code sicher um einiges nochmal größer (und langsamer?) machen. Das war jetzt natürlich nicht das Thema dieses Tests, schon klar.

    btw. ne Zufallszahl würde das Problem IMO auch nicht beheben. Ich will jetzt aber nichts unterstellen, vielleicht ist das Programm wirklich so schnell. Mich verwundert es halt zumindest, dass der Unterschied zwischen Debug und Release so gigantisch groß ist. 🙂



  • Optimizer schrieb:

    Nein, zeigt es IMHO nicht. Denn dazu müsste Volkard jetzt noch einen GC coden, um auf den selben Stand zu kommen (den wir bei dem Java-Programm haben), damit man von automatisiertem Speichermanagement sprechen kann. 😉
    Das würde den Code sicher um einiges nochmal größer (und langsamer?) machen. Das war jetzt natürlich nicht das Thema dieses Tests, schon klar.

    Die Idee von einem automatisierten Speichermanagement ist ja unter anderem, dass man da nichts selbst "coden" muss.



  • ..



  • Gregor schrieb:

    Trotzdem bin ich entsetzt, welchen Aufwand man treiben muss, um da entsprechende Performance herauszuholen.

    wieso? waren doch nur 1,5 jährchen.

    IMHO zeigt dieses Beispiel sehr eindrucksvoll, wie nützlich und mächtig ein automatisiertes Speichermanagement ist.

    nee. es ist erschreckend, daß das normale new/delete vom msvc für kleine objekte so lahm ist. beim oop werden nunmal richtig viele kleine objekte mit new angelegt. dem sollte die implementierung von new stärkstens rechnung tragen, hat sie aber nicht.



  • SirLant schrieb:

    Das gleiche habe ich auch gedacht Gregor, wenn man will kann man mit C++ schneller sein, jedoch muss man dafür einigen Aufwand betreiben, man vergleiche einmal beide Programme.

    naja, eigenlich sollte so ein allocator mitgeliefert sein und 10 weitere auch, alle mit speziellen vorzügen und nachteilen. das sind aber keine dabei. die mitgelieferten bibliotheken zu c++ sind einfach unnett und die zu java sind nett. normalerweise ist c++ ja nen tick schneller, hier hat gregor halt ein dickes versäumnis aufgedeckt.

    daß es uns an libs mangelt, kommt ein wenig daher, daß die c++-gemeinde sich wie tollwütig auf den hinterletzten trick mit metaprogramming stürzt und unlesbaren kram wie

    template<size_t SIZE>
    struct SizeToAllocatorIndex
    {
    	enum{CALL=SIZE%2==0?SIZE/2:SIZE+1};
    	enum{OFFSET=SIZE%2==0?2:0};
    	enum{VALUE=OFFSET+SizeToAllocatorIndex<CALL>::VALUE};
    };
    

    bastelt. also noch mit der beherrschung der sprache schwer kämft, statt inhaltliche fortschritte machen zu können.



  • Optimizer schrieb:

    Nein, zeigt es IMHO nicht. Denn dazu müsste Volkard jetzt noch einen GC coden, um auf den selben Stand zu kommen (den wir bei dem Java-Programm haben), damit man von automatisiertem Speichermanagement sprechen kann.

    das hieße aber c++ zu vergewaltigen. wir brauchen keinen gc. zur not könnte man mit smart pointers unter geringstem aufwand ne automatische freigabe machen.



  • nett, wirklich nett. 🙂

    bye

    tt

    PS: volkard, wie lange hast du gebraucht um die Theorie des smartbuddyallokators zu verstehen? Wo lagen die größten Probs bei deiner "Entwicklung"?



  • TheTester schrieb:

    volkard, wie lange hast du gebraucht um die Theorie des smartbuddyallokators zu verstehen?

    smartbuddyallocator? kenn ich net.
    hier hab ich nur nen small object allocator.
    den im wesentlichen zu verstehen, hat ungefähr 2 sekunden gebraucht. ist ja nur ne einfach verkettete liste von objekten, die ich statt sie wegzuschmeißen mit in der liste merke.
    meinen ersten funktionierenden hatte ich 1997 gebaut. der hat aber eher zufällig funktioniert.

    Wo lagen die größten Probs bei deiner "Entwicklung"?

    bei dem jetzt war das riesenproblem, die rekursiven funktionen wie int ai(int s) zu finden. hat mich mehr als ne stunde gekostet.

    ich hatte aber damals nicht gedacht, daß ein small object allocator mich in diesem thread weiterbringen würde. und alexandrescus small object allocator hat mich weit zurückgeworfen, sowas wollte ich einfach nicht. der setzt außerdem nur auf new auf. ich wollte auf rohen speicher vom bs aufsetzen, umd maximale performance haben zu können (um alles unter kontrolle zu haben).
    also ein normales malloc/free basteln und evtl ein wenig mit tricks zuckern. aber das ist nicht so leicht, vor allem, wenn man keine doku findet. und wenn man der doku einfach nicht glaubt! lineares durchschreiten der liste, um nächsen passenden block zu finden. da kann ich ja gleich nen 64-er nehmen. zwei zeiger davor und ein zeiger dahinter (vor/hinter dem allokierten dem nutzer gegebenen bereich). ich dachte eigentlich an ungefähr zero overhead. naja, ein prozent tut mir auch nicht weh.
    durch buha bin ich dann auf den buddy allocator gekommen. wenn die das in nem programming contest verlangen, muß es kinderleicht sein. und wie ich feststellte ist er superschnell und hat auch nur das eine prozent overhead, falls der benutzer immer zweierpotenzen allokiert. (mein small object allocator hat 16bytes/4096bytes plus verschnitt). den buddy allocator hab ich dann lange reifen lassen. (sicher war schon seit 1990, daß ich mal einen allocator bauen muß, da ich sonst nicht gut persitente daten auf der platte verwalten kann. muß ja im plattenfile platz allokieren und freigeben können.) aber ich hatte ständig was anderes zu tun. na, wenigstens nicht die power, ne woche an was ganz schwierigem zu basteln. und sowas kann man nicht fallenlassen und später weitermachen. und jetzt hab ich grad nen programmierschub, wo mir die verzwicktesten sachen gelingen, da hab ich den buddy allocator mal angefangen und die erste version klappt auch. damit (mirt dem buddy allocator und dem schub) bewaffnet hab ich dann diesen thread aufgemacht.

    und gelernt hab ich, daß ich für ein ernsthaftes system drei allokatoren brauche, nen buddy alocator für's grobe >256b oder so, einen für seiten 4k (queue und so, aber auch der small object allocator brauchen enorm schnell einzelne seiten) und den small object allocator für kleines.
    das lass ich jetzt wieder ne lange zeit gären.


Anmelden zum Antworten