Inwieweit sollte wissenschaftliche Software optimiert werden?

13

Bei Anwendungen, die erhebliche Rechenressourcen erfordern, kann eine hohe Leistung ein entscheidender Faktor sein, wenn es darum geht, wissenschaftliche Ergebnisse zu liefern oder in angemessener Zeit "Durchbrüche" zu erzielen.

Wie viel Zeit und Aufwand sollten Softwareentwickler in die Optimierung einer Anwendung investieren? Was sind die wichtigsten Kriterien?

Allan P. Engsig-Karup
quelle
Von Wissenschaftlern geschriebene Programme laufen oft sehr lange (zB Simulationen). Programmiererzeit und Computerlaufzeit sind möglicherweise vergleichbar. Dies unterscheidet sich sehr von der heutigen "üblichen" Programmiererarbeit. Wie in den frühen Tagen des Computerbetriebs lohnt es sich oft, etwas Mühe (und Zeit für Programmierer) zu investieren, um die Simulation zu beschleunigen und schneller zu beenden und die Arbeit schneller zu erledigen.
Szabolcs

Antworten:

15

In den allermeisten Fällen sind Verbesserungen der Algorithmen wichtiger als Verbesserungen der Optimierung. Algorithmen sind auch portabler als einfache Optimierungen. Mein Rat ist, allgemeine Best Practices in Bezug auf das Speicherlayout für die Wiederverwendung von Caches zu befolgen, übermäßige Kopien oder Kommunikation zu vermeiden, das Dateisystem auf eine vernünftige Weise zu behandeln und Gleitkommakerne für die Vektorisierung ausreichend granular zu machen. Manchmal reicht dies aus, um einen akzeptabel hohen Anteil an "Peak" zu erreichen (für diese Operation).

Skizzieren Sie immer ein Leistungsmodell für Vorgänge, die Sie für wichtig halten (oder die Sie durch die Profilerstellung als wichtig erachten). Anschließend können Sie anhand des Leistungsmodells abschätzen, welche Ergebnisse eine hochgradig optimierte Implementierung liefern könnte. Wenn Sie der Meinung sind, dass sich eine Beschleunigung lohnt (im Verhältnis zu den anderen möglichen Maßnahmen), nehmen Sie die Optimierung vor.

Die vielleicht größte Herausforderung besteht darin, wichtige Schnittstellen und Datenstrukturen auf hoher Ebene (in dem Sinne, dass viel Code von diesen Auswahlmöglichkeiten abhängt) zu entwerfen, damit Sie später optimieren können, ohne die API ändern zu müssen. Im Gegensatz zu bestimmten Optimierungen und allgemeinen Richtlinien kann ich dies nur durch Erfahrung lehren. Das Arbeiten mit leistungsabhängiger Open Source-Software hilft. Wie bei jeder API-Entscheidung ist es wichtig, den Problembereich zu verstehen.

Jed Brown
quelle
1
Erst kürzlich habe ich die Laufzeit eines begrenzenden Schritts unserer Analyse um den Faktor 10.000 (für unsere größten Ereignisse) verbessert, indem ich einen Algorithmus, der zeitlich und räumlich O (n ^ 2) war, durch einen O (n log n) ersetzte ) sowohl. Wohlgemerkt, es bedeutete eine weitere Abhängigkeit und zusätzliche Komplexität, aber manchmal lohnt es sich ...
dmckee --- Ex-Moderator Kätzchen
1
Beschleunigungsfaktoren (die relativ zu etwas sind) sind einen klaren Bezug zu dem, mit dem Sie verglichen haben, nicht viel wert. Wenn Sie mit einer schlechten Implementierung vergleichen, die auf einem unangemessenen Algorithmus basiert, und diese dann ändern, ist es offensichtlich nicht unangemessen, große relative Gewinne zu erwarten.
Allan P. Engsig-Karup
1
@Allan: Es gab einen Faktor von 10.000 für eine einzelne Änderung, dann war es offensichtlich eine schlecht gewählte Implementierung. Der vorherige Code wurde sowohl durch den unnötigen Speicherplatz als auch durch die zeitliche Komplexität geschädigt: Die Caching-Leistung war miserabel. Aber darum geht es doch, oder?
dmckee --- Ex-Moderator Kätzchen
8

Wie würden Sie "optimieren" definieren? Es gibt ein ganzes Spektrum von der Entwicklung besserer Algorithmen oder Rechenmodelle bis hin zur Verwendung von handgestimmten Assemblern.

Nach meiner Meinung und Erfahrung liegt die niedrig hängende Frucht irgendwo in der Mitte, z. B. bei der Auswahl eines Algorithmus, der für die zugrunde liegende Computerarchitektur am besten geeignet ist. Der Algorithmus muss nicht unbedingt neu sein und Ihr Verständnis der zugrunde liegenden Architektur muss nicht unbedingt sehr spezifisch sein, z

  • Wenn Sie wissen, dass Ihre Architektur SIMD unterstützt, strukturieren Sie die Berechnung so, dass Ihre Operationen in Form von kurzen Vektoren geschrieben werden können.
  • Wenn Sie wissen, dass Ihre Architektur ein Mehrkerncomputer ist, versuchen Sie, Ihre Rechenaufgabe in einzelne Unteraufgaben zu unterteilen, die sich nicht gegenseitig stören, und führen Sie sie parallel aus (denken Sie an eine DAG Ihrer Unteraufgaben). ,
  • Wenn Ihre zugrunde liegende Architektur eine GPU hat, überlegen Sie, wie Sie Ihre Berechnung als eine Gruppe von Threads neu formulieren können, die in Sperrschritten durch die Daten marschieren.
  • etc...

Auf alle oben genannten Funktionen, z. B. SIMD, Parallelität und GPUs, kann ohne viel geringes Wissen zugegriffen werden, sie bieten jedoch nur einen Vorteil bei Algorithmen, die diese Funktionen problemlos nutzen können.

Pedro
quelle
4

Ich stimme allen bisher gegebenen Antworten zu ... Ich möchte nur einen weiteren Aspekt der Codeoptimierung übersehen: die Qualitätserwartung.

Das Problem der Codeoptimierung tritt normalerweise auf, wenn der Benutzer versucht, immer größere Probleme zu lösen, und der Code nicht ausreicht, um die Anforderungen / Erwartungen des Benutzers zu erfüllen. Die Zeit, die man in die Codeoptimierung investieren sollte, hängt von der Nachfrage ab, um diese Erwartung zu erfüllen. Es lohnt sich auf jeden Fall, viel Zeit zu investieren, wenn ein entscheidender Wettbewerbsvorteil erforderlich ist (z. B. Abschluss und Veröffentlichung Ihrer Forschung zu einem wichtigen Thema vor anderen).

Wie viel Zeit investiert werden muss, hängt natürlich davon ab, wie schnell und wie portabel der Code sein soll. Oft stehen diese beiden Anforderungen in Konflikt miteinander und Sie müssen entscheiden, was wichtiger ist, bevor Sie mit der Optimierung beginnen. Je portabler Sie es möchten, desto mehr müssen Sie sich auf allgemeine Designänderungen am Code (Algorithmus / Datenstruktur) verlassen. Je schneller der Code ausgeführt werden soll, desto geringer müssen die Optimierungen sein, die für einen bestimmten Computer spezifisch sind (z. B. Code- / Compiler- / Laufzeitoptimierungen).

Paul
quelle
4

Sie müssen die (Kosten-) Analyse durchführen, um so viele Mannmonate (und diese sind immer mythisch :-)) für die Steigerung der Ausführungsgeschwindigkeit aufzuwenden. Sie müssen herausfinden, wie oft diese Software verwendet wird und von wie vielen Personen, damit Sie den Gewinn abschätzen können.

Die Faustregel ist wie immer die berühmte 80/20 Regel. Manchmal summiert es sich einfach nicht mehr, immer mehr Zeit damit zu verbringen, ein paar Prozent (oder weniger) der Laufzeit zu gewinnen. Aber du musst analysieren.

Und ich stimme den oben genannten Aussagen aufrichtig zu: Stellen Sie sicher, dass Ihre API gut durchdacht ist, sodass nicht viele Änderungen erforderlich sind, und stellen Sie sicher, dass der Code portierbar und wartbar ist (denken Sie daran, dass Sie einen von Ihnen geschriebenen Algorithmus erneut analysieren müssen, und zwar ohne weiteres vor zehn Jahren optimiert). Und stellen Sie sicher, dass Sie gute Programmierpraxis und Standardbibliotheken verwenden. Die Chancen stehen gut, dass jemand bereits über den effizientesten Algorithmus für Ihre Anwendung nachgedacht hat.

Um Donald Knuth zu zitieren: "Vorzeitige Optimierung ist die Wurzel allen Übels". So profilieren Sie Ihren Code, aber nicht zu früh.

GertVdE
quelle
Beziehen Sie sich auf die Pareto-Prinzip-Regel (80/20)? Wenn ja, sollten wir die Optimierungsbemühungen auf 20% des Codes konzentrieren, der 80% der Verlangsamung erzeugt? Oder meinst du damit, dass es sich einfach nicht lohnt, zu optimieren, wenn du nur eine Beschleunigung von 20% erwarten kannst?
Paul
Nein, ich habe es nur als eine Art Prinzip verwendet, nicht genau 80/20. Zu einem bestimmten Zeitpunkt werden Sie sich so viel Mühe geben, um nur ein paar Prozentpunkte zu erreichen, dass sich die Mühe nicht mehr lohnt.
GertVdE,
3

Einige zusätzliche Ratschläge:

  1. Stellen Sie vor der Optimierung eines Arbeitsprogramms sicher, dass Sie über eine Reihe von Testfällen verfügen, die zur Aufrechterhaltung der Integrität des Codes beitragen. Es hat keinen Sinn, falsche Ergebnisse schneller zu erzielen.
  2. Wenn Ihre Optimierung den Code weniger lesbar macht, behalten Sie die Originalversion bei, zumindest in Form eines Kommentars, aber besser als alternative Version, die zur Kompilierungs- und Laufzeit ausgewählt wird. Ihre Optimierungsanforderungen können sich ändern, wenn sich Ihre Probleme und Maschinen weiterentwickeln, und der ursprüngliche Code ist möglicherweise ein besserer Ausgangspunkt für die Optimierung, die Sie in fünf Jahren durchführen werden.
  3. Wenn sich herausstellt, dass Ihre optimierte Version nur minimale Auswirkungen hat, den Code jedoch weniger lesbar, universeller oder weniger stabil macht, kehren Sie zur Originalversion zurück. Sie verlieren mehr als Sie gewinnen.
khinsen
quelle