Anzeige:
Ergebnis 1 bis 7 von 7

Thema: [c++] valarray halten nicht was sie versprechen

  1. #1
    Registrierter Benutzer
    Registriert seit
    19.02.2004
    Beiträge
    10

    [c++] valarray halten nicht was sie versprechen

    Hallo

    Ich wollte für ein Bildverarbeitungsproblem (für ein Echtzeitsystem) Berechnungen, die derzeit mit vector laufen auf valarray umstellen. In verschiedenen Büchern und Texten im Web werden diese als für numerische Berechnungen optimierte "Arrays" angepriesen. Leider kann ich das bei mir hier nicht ganz nachvollziehen. Im Gegenteil ich hab hier ein einfaches Beispiel bei dem sie deutlich langsamer sind.

    Hier ist mal mein kleines Testprogramm
    Code:
    #include <iostream>
    #include <valarray>
    #include <vector>
    #include <cstdlib>
    
    { ... schnipp schnapp .. }
    
    int main() {
    
    { ... schnipp schnapp .. }
    
      vector<float> vFloat(tSize);
      vector<int> vInt(tSize);
    
      tTime.set();
      for (int r = 0; r != Runs; ++r) {
        for (size_t i = 0; i != vFloat.size(); ++i) {
          vFloat[i] *= fFloat;
        }
      }
      tDur.set(tTime);
      cout << endl;
      cout << "Vector: vector<float> elementweise mit float mulitpliziert" << endl;
      cout << "Vector: size=" << vFloat.size() << " runs=" << Runs << " duration=" << tDur.get() << endl;
    
      tTime.set();
      for (int r = 0; r != Runs; ++r) {
        for (size_t i = 0; i != vInt.size(); ++i) {
          vInt[i] *= 4;
          vInt[i] /= 5;
        }
      }
      tDur.set(tTime);
      cout << endl;
      cout << "Vector: vector<int> elementweise * 4 / 5" << endl;
      cout << "Vector: size=" << vInt.size() << " runs=" << Runs << " duration=" << tDur.get() << endl;
    
      //######################################################
    
      valarray<float> vaFloat(tSize);
      valarray<int> vaInt(tSize);
    
      tTime.set();
      for (int r = 0; r != Runs; ++r) {
        vaFloat *= fFloat;
      }
      tDur.set(tTime);
      cout << endl;
      cout << "Valarray: valarray<float> elementweise mit float mulitpliziert" << endl;
      cout << "Valarray: size=" << vaFloat.size() << " runs=" << Runs << " duration=" << tDur.get() << endl;
    
      tTime.set();
      for (int r = 0; r != Runs; ++r) {
        vaInt *= 4;
        vaInt /= 5;
      }
      tDur.set(tTime);
      cout << endl;
      cout << "Valarray: valarray<int > elementweise * 4 / 5" << endl;
      cout << "Valarray: size=" << vaInt.size() << " runs=" << Runs << " duration=" << tDur.get() << endl;
    }
    Ich habe dieses auf ein Linux PC (Pentium 4) compiliert (gcc 3.4.3,-O2) und ausgeführt. Das Ergebniss war unerwartet:

    Code:
    Vector: vector<float> elementweise mit float mulitpliziert
    Vector: size=1000000 runs=100 duration=2047.86
    
    Vector: vector<int> elementweise * 4 / 5
    Vector: size=1000000 runs=100 duration=2130.25
    
    Valarray: valarray<float> elementweise mit float mulitpliziert
    Valarray: size=1000000 runs=100 duration=2051.39
    
    Valarray: valarray<int > elementweise * 4 / 5
    Valarray: size=1000000 runs=100 duration=7566.39
    also bei Int werten ist valarray um den Faktor 4 langsamer als ein von Hand multiplizierter Vektor. Und auch bei der Float Variante gewinne ich keinerlei Zeit. Ich hab auch mit Optionen wie -msse u.ä. oder -march probiert mit dem gleichen Ergebnis.

    Kann mir evtl jemand sagen, ob ich etwas falsch verstanden habe oder einen logischen Denkfehler unterliege? Ich kann mir diese Ergebnisse nur noch erklären mit einer schlechten Implementation von valarrays in der mir vorliegenden Version.

    Gruss Hannes

  2. #2
    Registrierter Benutzer Avatar von SeeksTheMoon
    Registriert seit
    22.02.2002
    Beiträge
    762
    "Die Standardbibliothek enthält zur Unterstützung numerischer Operationen auf großen Feldern typgleicher Elemente den Container valarray. Man kann ihn sich wie eine Version von vector vorstellen, dessen Länge sich einmalig dynamisch festlegen lässt, der aber daraufhin optimiert ist, dass sich diese Länge später nicht mehr ändert."

    heißt es im Netz. Ich lese keinen Hinweis, dass es für Zahlenwerte optimiert ist.
    I haven't lost my mind - It's somewhere on a backup-disc

  3. #3
    Registrierter Benutzer
    Registriert seit
    16.09.2001
    Beiträge
    1.182

    Sollte ja eigentlich schon...

    Eigentlich stimmts ja, der Compiler weiß ja dass auf alle Elemente die selbe Operation ausgeführt werden soll und sollte darauf hin Optimierungen durchführen können (z.B. vektorisieren) ohne den Quellcode zuerst kompliziert analysieren zu müssen.

    Ich würds zuerst einmal mit gcc-4.1 ausprobieren und wenns da nicht funtzt mal den icc-9.1 auspribieren auf der gcc mailingliste nachfragen wieso's der kann und der gcc nicht .
    Geändert von Lin728 (21-08-2017 um 14:58 Uhr)

  4. #4
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von SeeksTheMoon
    heißt es im Netz. Ich lese keinen Hinweis, dass es für Zahlenwerte optimiert ist.
    Im Stroustroup steht da schon anderes. Da hat der OP schon recht, valarray sollte diesbezüglich optimiert sein.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  5. #5
    Registrierter Benutzer
    Registriert seit
    19.02.2004
    Beiträge
    10
    Wir haben verschiedene Compiler getestet. Leider sind wir auf den gcc angewiesen. Sobald wir beim kompilieren -O2 eingeschaltet haben, hatten die Valarrays verloren. Stellenweise wurden sie sogar langsamer. Erst ab einer größe von > 500MB wurden sie wieder schneller.

    Ich dachte dass die valarray gerade durch Vektoriesierung optimiert werden können. Dazu stehen meiner Meinung auch die Prozessor Features SSE und SSE2.

    Schade das es in der Realität nicht ganz so schön ist.
    gruss Hannes

  6. #6
    Registrierter Benutzer Avatar von Detrius
    Registriert seit
    09.03.2004
    Ort
    Altena
    Beiträge
    64
    Ist vielleicht Blitz++ was für Dich?

  7. #7
    Registrierter Benutzer
    Registriert seit
    25.10.2004
    Beiträge
    819
    Zitat Zitat von Akleson
    Ich dachte dass die valarray gerade durch Vektoriesierung optimiert werden können. Dazu stehen meiner Meinung auch die Prozessor Features SSE und SSE2.
    Kompiliert ihr denn auch mit
    Code:
    -march=athlonxp -msse2 -mfpmath=sse -O2
    (Statt "athlonxp" natürlich den entsprechenden Prozzi einsetzen)

    Bzw: Wurde die STL-Library auch mit diesen Optionen compiliert? Debians' vorgefertigte Pakete z.B. sind immer für den 80386 optimiert.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •