restrict in C++ unnötig?



  • In diesem Forum sind scheinbar sogar die Moderatoren C++-Trolle.

    SeppJ schrieb:

    Restrict: Brauchste in C++ nicht, weil du in C++ praktisch niemals Code schreiben würdest, der Aliasingprobleme hat. Das ist ein typisches C-Problem, eben wegen der Beschränkungen von C.

    Kann mir jemand zeigen, wie man das in diesem Beispiel machen würde?

    void inner_product(int*restrict r, int*restrict a, int*restrict b, int n)
    {
      while (n--)
        *r++ = *a++ * *b++;
    }
    
    void my_inner_product(int* a, int* a_end, int* b, int* c)
    {
      while (a != a_end)
        *c++ = *a++ * *b++;
    }
    

    Programm:

    #include <stdio.h>
    #include <stdlib.h>
    
    void inner_product(int*restrict r, int*restrict a, int*restrict b, int n);
    
    int main(int argc, char *argv[])
    {
      const int size  = 10;
      const int loops = 100000000;
      int *mem = malloc(3*size*sizeof(*mem));
      int *a = mem, *b = a+size, *c = a+2*size;
    
      for (int i=0; i<size; ++i) {
        a[i] = i;
        b[i] = i;
      }
    
      for (int i=0; i<loops; ++i) {
        inner_product(c, a, b, size);
        int *t = a; a = b; b = c; c = t;
      }
    
      free(mem);
    
      printf("%d %d %d\n", a[atoi(argv[1])], b[atoi(argv[2])], c[atoi(argv[3])]);
      return 0;
    }
    
    #include <cstdlib>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    using namespace std;
    
    void my_inner_product(int* a, int* a_end, int* b, int* c);
    
    int main(int argc, char *argv[])
    {
      const int size  = 10;
      const int loops = 100000000;
    
      vector<int> mem(3*size);
      int * a = mem.data();
      int * b = a+size;
      int * c = a+2*size;
    
      for (int i=0; i<size; ++i) {
        a[i] = i;
        b[i] = i;
      }
    
      for (int i=0; i<loops; ++i) {
        my_inner_product(a, a+size, b, c);
        swap(a, b); // 1 2 3 -> 2 1 3
        swap(b, c); // 2 1 3 -> 2 3 1
      }
    
      {
        int tmp_i;
        istringstream is(argv[1]); is >> tmp_i;
        cout << a[tmp_i] << " ";
      }
      {
        int tmp_i;
        istringstream is(argv[2]); is >> tmp_i;
        cout << b[tmp_i] << " ";
      }
      {
        int tmp_i;
        istringstream is(argv[3]); is >> tmp_i;
        cout << c[tmp_i] << endl;
      }
    }
    

    Kompiliert mit

    g++ -O3 -march=native -c ser.cc
    g++ -O3 -march=native -c ser_.cc
    g++ ser.o ser_.o -o ser
    
    gcc -std=c99 -O3 -march=native -c res.c
    gcc -std=c99 -O3 -march=native -c res_.c
    gcc -std=c99 res.o res_.o -o res
    

    (Ja, es ist absichtlich in zwei Dateien, damit die Methode nicht geinlined wird. Bitte beibehalten.)

    C:
    real 0m2.441s
    user 0m2.437s
    sys 0m0.000s
    ser

    C++
    real 0m2.911s
    user 0m2.910s
    sys 0m0.000s


  • Mod

    Restrict++ schrieb:

    In diesem Forum sind scheinbar sogar die Moderatoren C++-Trolle.

    SeppJ schrieb:

    Restrict: Brauchste in C++ nicht, weil du in C++ praktisch niemals Code schreiben würdest, der Aliasingprobleme hat. Das ist ein typisches C-Problem, eben wegen der Beschränkungen von C.

    Dann zitier auch den Rest:

    SeppJ schrieb:

    Ich wusste, als ich es schrieb, dass da schon wieder so ein Klugscheißer kommt, der irgendwelche obskuren Sprachfeatures nennen wird, die zwar kein Mensch benutzt, aber mit denen sich eventuelle Beispiele künstlich konstruieren lassen.

    Damit:

    Restrict++ schrieb:

    Ja, es ist absichtlich in zwei Dateien, damit die Methode nicht geinlined wird. Bitte beibehalten.

    Lol. schließen wir also genau das aus, wovon du genau weißt, dass dies der Grund ist, warum du restrict in C++ nicht brauchst. Künstlich konstruiertes Beispiel. Da man somit sofort erkennt, dass du an keiner ernsthaften Diskussion interessiert bist, kann ich meine und aller anderen Leute Zeit sparen: [/closed].


Anmelden zum Antworten