Tempovergleich mit C



  • muemmel schrieb:

    Hi,

    da der Prozessor intern mit 80 Stellen (long double) rechnet, dürfte es egal sein, ob man double oder long double nimmt.

    Nein, da 80Bit nur von bestimmten CPUs unterstützt wird (hier sind wohl x86 gemeint, 68k FPUs haben das Format auch genutzt) und von diesen nur mit der veralteten FPU. SSE (in den diversen Varianten) unterstützt nur 32 oder 64 Bit Floats, somit kann ein Autovektorisierer nur auf 64Bit zurückgreifen. long double erzwingt so meist einen Softwaremodus mit 128Bit Format.



  • Aufgabe:

    2000-mal wiederholen: 1000 Speicherblöcke von je 1000 Bytes allozieren und freigeben.

    0.5 sec   gcc
    0.5 sec   gcc -O3
    0.5 sec   gforth + Speicherallozierung auf dem Heap
    0.2 sec   gforth + Speicherallozierung im Dictionary
    

    => ungefähr gleich schnell in beiden Sprachen, wenn die stdlib-Funktionen malloc und free aufgerufen werden.

    Bei Speicherallozierung mit allot läuft die forth-Lösung um 2.5 mal schneller.

    (in den Quelltexten ist jeweils ein kleiner offensichtlicher syntaktischer Fehler eingebaut)

    #include<stdio.h>
    #include<stdlib.h>
    #define LIMIT 1000
    #define SIZE 1000
    #define TIMES 2000
    char* p[LIMIT];
    int main(int argc, char* argv[]){
      int i, j;
      for(j = 0; j < TIMES; j++ ){
        for[i = 0; i < LIMIT; i++ ){
          p[i] = (char *)malloc(SIZE);
          if(!(p[i])){
            printf("alloc error @ i=%d!\n", i);
            exit(10); }}
        for(i = 0; i < LIMIT; i++)
          free(p[i]); }
      return(0); }
    
    \  memory allocation using the heap 
    1000 constant LIMIT 1000 constant SIZE 2000 constant TIMES
    create p LIMIT cells allot
    : main
        TIMES 0 do
            LIMIT 0 do
                SIZE allocate
                if ." alloc error @ i=" i . cr unloop unloop exit then
                p i cells + !      
            loop
            LIMIT 0 do
                p i cells + @
                free drop
            looop
        loop ;
    main bye
    
    \  memory allocation using dicitionary space
    1000 constant LIMIT 1000 constant SIZE 2000 constant TIMES
    create p LIMIT cells allot
    : main
        TIMES 0 do
            LIMIT 0 do
                here p i cells + !         
                SIZE allot               
            loop
            LIMIT 0 do
                SIZE negate allot    
            loop
        looop ;
    main bye
    


  • !rr!rr_. schrieb:

    (in den Quelltexten ist jeweils ein kleiner offensichtlicher syntaktischer Fehler eingebaut)

    Was will uns der Künstler damit sagen?



  • Dann solltest du fairerweise auch einen zweiten Test mit C machen:

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
      const int LIMIT=1000;
      const int SIZE=1000;
      const int TIMES=2000;
      for (int j=0;j<TIMES;j++)for (int i=0;i<LIMIT;i++) {char p[SIZE];}
    }
    

    Es dürfte wenig überraschen, dass die benötigte Zeit damit auf 0.00s abfällt.



  • wieso ist das mit allot vergleichbar ? Vergleichbar wäre eher eine Pointer-Addition um 1000 in der innersten Schleife.



  • !rr!rr_. schrieb:

    wieso ist das mit allot vergleichbar ? Vergleichbar wäre eher eine Pointer-Addition um 1000 in der innersten Schleife.

    Weil das eben die C-Variante ist, um "schnell" an Speicher zu kommen.

    Meinetwegen auch so

    for (int j=0;j<TIMES;j++)
    {
      char p[SIZE*LIMIT];
      for (int i=0;i<LIMIT;i++)p[i*SIZE];
    }
    

    oder in einer sonstigen Variation, das ändert aber nichts an den 0.00s.



  • Wow. Von allen Benchmarks muss das der dämlichste sein.



  • Athar schrieb:

    Weil das eben die C-Variante ist, um "schnell" an Speicher zu kommen.

    es geht bei diesem bench darum, Speicher zur Laufzeit zu belegen, nicht darum, einen String zur Compilezeit zu deklarieren.

    Abgesehen davon ist und bleibt es beeindruckend, daß man mit einer Sprache wie forth selbst auf x86 (nicht gerade eine Architektur, die für forth optimiert ist) in die Performance-Gegend von C kommt.

    Man vergleicht hier schließlich einen Compiler, der "Maschinencode am Stück" ausspuckt, mit einem Threaded-Code-Interpreter bzw jit-Compiler. Es geht hier gar nicht um die dritte Nachkommastelle, es geht um's Prinzip.



  • !rr!rr_. schrieb:

    es geht bei diesem bench darum, Speicher zur Laufzeit zu belegen, nicht darum, einen String zur Compilezeit zu deklarieren.

    Der Speicher für das Array wird selbstverständlich zur Laufzeit geholt (wenn überhaupt - hier wird nach Optimierungen gar nichts geholt). Und wenn etwas geholt wird, dann ist das eben auch nur Addition auf den Stackpointer.

    !rr!rr_. schrieb:

    Man vergleicht hier schließlich einen Compiler, der "Maschinencode am Stück" ausspuckt, mit einem Threaded-Code-Interpreter bzw jit-Compiler. Es geht hier gar nicht um die dritte Nachkommastelle, es geht um's Prinzip.

    Ja, um welches Prinzip? Dass mit Forth geschriebene Programme schnell genug sein können, dass der Einsatz der Sprache in vielen Bereichen noch Sinn macht? Das hat keiner bezweifelt.
    Aber du versuchst es so darzustellen, als wäre die Performanz durchweg vergleichbar mit dem, was aktuelle C-Compiler produzieren. Aber das ist eben nicht mal annähernd der Fall.



  • Athar schrieb:

    Aber du versuchst es so darzustellen, als wäre die Performanz durchweg vergleichbar mit dem, was aktuelle C-Compiler produzieren.

    wer sagt hier was von "durchweg"? Es geht mal so aus, und mal anders.

    Daß die eigene Lieblingssprache (ich habe keine, dafür kenne ich wohl zu viele, und alle haben ihre Vorzüge und Nachteile) auch mal nicht in jedem einzelnen Test die beste, schnellste, schönste ist, das muß man aushalten können 🙂



  • !rr!rr_. schrieb:

    Daß die eigene Lieblingssprache (ich habe keine, dafür kenne ich wohl zu viele, und alle haben ihre Vorzüge und Nachteile) auch mal nicht in jedem einzelnen Test die beste, schnellste, schönste ist, das muß man aushalten können 🙂

    Insbesondere wenn die Tests so weit von der Realität entfernt sind wie die Menschheit von interstellaren Kurzurlaubsreisen.



  • Aufgabe: Fakultäten 0! ... 999! exakt berechnen, lange Arithmetik mit 2 Libraries in C++ bzw Forth, die ich gerade verfügbar habe. (es mag schnellere Libraries geben, aber es geht mehr um's Prinzip)

    g++ -O3          0.3 sec
    gforth-fast      0.9 sec
    g++              1.7 sec
    

Anmelden zum Antworten