476 Stimmen

Ist Fortran für umfangreiche Berechnungen leichter zu optimieren als C?

Von Zeit zu Zeit lese ich, dass Fortran bei schweren Berechnungen schneller ist oder sein kann als C. Ist das wirklich so? Ich muss zugeben, dass ich Fortran kaum kenne, aber der Fortran-Code, den ich bisher gesehen habe, hat nicht gezeigt, dass die Sprache Funktionen hat, die C nicht hat.

Wenn dies der Fall ist, sagen Sie mir bitte, warum. Bitte sagen Sie mir nicht, welche Sprachen oder Libs gut für Number Crunching sind, ich habe nicht vor, eine App oder Lib zu schreiben, um das zu tun, ich bin nur neugierig.

517voto

Nils Pipenbrinck Punkte 80152

Die Sprachen weisen ähnliche Merkmale auf. Der Leistungsunterschied ergibt sich aus der Tatsache, dass in Fortran Aliasing nicht erlaubt ist, es sei denn, es wird eine EQUIVALENCE-Anweisung verwendet. Jeder Code, der Aliasing enthält, ist kein gültiger Fortran-Code, aber es ist Sache des Programmierers und nicht des Compilers, diese Fehler zu erkennen. Daher ignorieren Fortran-Compiler mögliche Aliasing-Fehler von Speicherzeigern und ermöglichen es ihnen, effizienteren Code zu erzeugen. Werfen Sie einen Blick auf dieses kleine Beispiel in C:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

Diese Funktion würde nach der Optimierung langsamer laufen als das Fortran-Pendant. Warum ist das so? Wenn Sie Werte in das Ausgabe-Array schreiben, können Sie die Werte der Matrix ändern. Schließlich könnten sich die Zeiger überschneiden und auf denselben Speicherbereich zeigen (einschließlich der int Zeiger!). Der C-Compiler ist gezwungen, die vier Matrixwerte für alle Berechnungen neu aus dem Speicher zu laden.

In Fortran kann der Compiler die Matrixwerte einmal laden und sie in Registern speichern. Dies ist möglich, weil der Fortran-Compiler davon ausgeht, dass sich Zeiger/Arrays im Speicher nicht überschneiden.

Glücklicherweise ist die restrict Schlüsselwort und strict-aliasing wurden in den C99-Standard aufgenommen, um dieses Problem zu lösen. Heutzutage wird es auch von den meisten C++-Compilern gut unterstützt. Mit dem Schlüsselwort können Sie dem Compiler einen Hinweis geben, dass der Programmierer verspricht, dass ein Zeiger nicht mit einem anderen Zeiger verwechselt werden darf. Striktes Alias bedeutet, dass der Programmierer verspricht, dass sich Zeiger unterschiedlichen Typs niemals überschneiden werden, z. B. ein double* überschneidet sich nicht mit einer int* (mit der besonderen Ausnahme, dass char* y void* kann sich mit allem überschneiden).

Wenn Sie diese verwenden, erhalten Sie die gleiche Geschwindigkeit von C und Fortran. Allerdings ist die Möglichkeit, die restrict Schlüsselwort nur bei leistungskritischen Funktionen bedeutet, dass C- (und C++-) Programme viel sicherer und einfacher zu schreiben sind. Betrachten Sie zum Beispiel den ungültigen Fortran-Code: CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30) die von den meisten Fortran-Compilern problemlos und ohne Warnung kompiliert wird, aber einen Fehler verursacht, der nur bei einigen Compilern, auf bestimmter Hardware und mit bestimmten Optimierungsoptionen auftritt.

181voto

jaredor Punkte 2154

Ja, im Jahr 1980; im Jahr 2008? hängt davon ab

Als ich mit der professionellen Programmierung begann, wurde die Geschwindigkeitsdominanz von Fortran gerade in Frage gestellt. Ich erinnere mich darüber in Dr. Dobbs zu lesen und erzählte den älteren Programmierern von dem Artikel - sie lachten.

Ich habe also zwei Ansichten dazu, eine theoretische und eine praktische. Theoretisch Fortran hat heute keinen intrinsischen Vorteil gegenüber C/C++ oder anderen Sprachen, die Assembler-Code zulassen. In der Praxis Fortran genießt auch heute noch die Vorteile einer Geschichte und Kultur, die auf die Optimierung von numerischem Code ausgerichtet ist.

Bis einschließlich Fortran 77 lag der Schwerpunkt der Überlegungen zum Sprachdesign auf der Optimierung. Aufgrund des Stands der Compiler-Theorie und -Technologie bedeutete dies oft Einschränkung Funktionen und Fähigkeiten, um dem Compiler die besten Möglichkeiten zur Optimierung des Codes zu geben. Eine gute Analogie ist es, sich Fortran 77 als einen professionellen Rennwagen vorzustellen, der Funktionen für Geschwindigkeit opfert. Heutzutage sind die Compiler in allen Sprachen besser geworden, und die Funktionen für die Produktivität der Programmierer werden mehr geschätzt. Es gibt jedoch immer noch Bereiche, in denen es den Leuten vor allem um Geschwindigkeit im wissenschaftlichen Rechnen geht; diese Leute haben höchstwahrscheinlich Code, Ausbildung und Kultur von Leuten geerbt, die selbst Fortran-Programmierer waren.

Wenn man anfängt, über die Optimierung von Code zu sprechen, gibt es viele Probleme, und der beste Weg, um ein Gefühl dafür zu bekommen, ist sich dort aufzuhalten, wo Leute sind, die einen schnellen Zahlencode haben . Aber bedenken Sie, dass solch kritischer Code in der Regel nur einen kleinen Teil der gesamten Codezeilen ausmacht und sehr spezialisiert ist: Ein großer Teil des Fortran-Codes ist genauso "ineffizient" wie ein großer Teil des Codes in anderen Sprachen und die Optimierung sollte nicht einmal ein Hauptanliegen eines solchen Codes sein .

Ein wunderbarer Ausgangspunkt, um mehr über die Geschichte und Kultur von Fortran zu erfahren, ist wikipedia. Der Fortran-Wikipedia-Eintrag ist großartig, und ich schätze diejenigen sehr, die sich die Zeit und Mühe genommen haben, es für die Fortran-Gemeinschaft wertvoll zu machen.

(Eine gekürzte Version dieser Antwort wäre ein Kommentar in dem ausgezeichneten Thread, der von Nils aber ich habe nicht das Karma, um das zu tun. Eigentlich hätte ich wahrscheinlich gar nichts geschrieben, aber dafür hat dieser Thread einen tatsächlichen Informationsgehalt und Austausch im Gegensatz zu Flame Wars und sprachlicher Bigotterie, was meine Haupterfahrung mit diesem Thema ist. Ich war überwältigt und musste die Liebe teilen).

70voto

user49734 Punkte 687

Bis zu einem gewissen Grad wurde Fortran mit Blick auf die Compileroptimierung entwickelt. Die Sprache unterstützt ganze Array-Operationen, bei denen Compiler die Parallelität ausnutzen können (insbesondere auf Mehrkernprozessoren). Zum Beispiel,

Die Multiplikation einer dichten Matrix ist einfach:

matmul(a,b)

Die L2-Norm eines Vektors x ist:

sqrt(sum(x**2))

Außerdem werden Aussagen wie FORALL , PURE & ELEMENTAL Prozeduren usw. helfen weiter, den Code zu optimieren. Selbst Zeiger in Fortran sind aus diesem einfachen Grund nicht so flexibel wie in C.

Der kommende Fortran-Standard (2008) verfügt über Co-Arrays, mit denen Sie problemlos parallelen Code schreiben können. G95 (Open Source) und Compiler von CRAY unterstützen dies bereits.

Ja, Fortran kann schnell sein, einfach weil die Compiler es besser optimieren/parallelisieren können als C/C++. Aber wie bei allem im Leben gibt es gute Compiler und schlechte Compiler.

42voto

Hossein Talebi Punkte 427

Es ist lustig, dass viele Antworten hier von Nicht-Kenntnissen der Sprachen stammen. Dies gilt insbesondere für C/C++-Programmierer, die alten FORTRAN 77-Code geöffnet haben und die Schwächen diskutieren.

Ich nehme an, dass die Frage der Geschwindigkeit hauptsächlich eine Frage zwischen C/C++ und Fortran ist. Bei einem Huge-Code kommt es immer auf den Programmierer an. Es gibt einige Funktionen der Sprache, die Fortran übertrifft, und einige Funktionen, die C bietet. Im Jahr 2011 kann also niemand wirklich sagen, welche Sprache schneller ist.

Was die Sprache selbst betrifft, so unterstützt Fortran heutzutage alle OOP-Funktionen und ist vollständig abwärtskompatibel. Ich habe Fortran 2003 ausgiebig benutzt und ich würde sagen, dass es einfach herrlich war, es zu benutzen. In einigen Aspekten ist Fortran 2003 noch hinter C++ zurück, aber schauen wir uns die Verwendung an. Fortran wird hauptsächlich für numerische Berechnungen verwendet, und niemand nutzt die ausgefallenen OOP-Funktionen von C++ aus Gründen der Geschwindigkeit. In der Hochleistungsinformatik hat C++ so gut wie keinen Platz mehr (sehen Sie sich den MPI-Standard an, und Sie werden sehen, dass C++ veraltet ist).

Heutzutage kann man mit Fortran und C/C++ einfach gemischtsprachig programmieren. Es gibt sogar Schnittstellen für GTK+ in Fortran. Es gibt freie Compiler (gfortran, g95) und viele ausgezeichnete kommerzielle Compiler.

33voto

Greg Rogers Punkte 34400

Es gibt mehrere Gründe, warum Fortran schneller sein könnte. Sie sind jedoch so unbedeutend oder können ohnehin umgangen werden, dass sie keine Rolle spielen sollten. Der Hauptgrund für den Einsatz von Fortran ist heutzutage die Wartung oder Erweiterung von Altanwendungen.

  • PURE und ELEMENTAL Schlüsselwörter für Funktionen. Dies sind Funktionen, die keine Nebeneffekte haben. Dies ermöglicht Optimierungen in bestimmten Fällen, in denen der Compiler weiß, dass dieselbe Funktion mit denselben Werten aufgerufen werden wird. Anmerkung: GCC implementiert "pure" als eine Erweiterung der Sprache. Andere Compiler können das auch. Die modulübergreifende Analyse kann diese Optimierung ebenfalls durchführen, aber das ist schwierig.

  • Standardfunktionen, die mit Arrays und nicht mit einzelnen Elementen arbeiten. Funktionen wie sin(), log(), sqrt() verwenden Arrays statt Skalare. Das macht es einfacher, die Routine zu optimieren. Die Auto-Vektorisierung bietet in den meisten Fällen die gleichen Vorteile, wenn diese Funktionen inline oder builtins sind

  • Eingebauter komplexer Typ. Theoretisch könnte dies dem Compiler ermöglichen, bestimmte Anweisungen in bestimmten Fällen neu anzuordnen oder zu eliminieren, aber wahrscheinlich würden Sie den gleichen Nutzen mit dem struct { double re; double im; }; Idiom, das in C verwendet wird. Es ermöglicht eine schnellere Entwicklung, da die Operatoren mit komplexen Typen in Fortran arbeiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X