Frage

Nach meiner Erfahrung ist .NET 2 bis 3-mal langsamer als native Code. (I umgesetzt L-BFGS für multivariate Optimierung).

Ich habe die Anzeigen auf Stackoverflow zurückzuführen http://www.centerspace.net/products/

ist die Geschwindigkeit wirklich erstaunlich, die Geschwindigkeit in der Nähe von nativen Code. Wie können sie das tun? Sie sagten, dass:

  

Q. Ist NMath "reine" .NET?

     

A. Die Antwort hängt etwas von Ihrer Definition von „reinen .NET“. NMath ist in C # geschrieben, plus eine kleine Managed C ++ Schicht. Für eine bessere Leistung der grundlegenden Operationen der linearen Algebra jedoch NMath angewiesen auf die native Intel Math Kernel Library (mit NMath enthalten). Aber es gibt keine COM-Komponenten, keine DLLs - nur .NET-Assemblies. Auch alle Speicher in der Managed C ++ Schicht zugeordnet und wird von nativen Code aus dem verwalteten Heap zugeordnet.

Kann jemand erklären mir mehr?

War es hilfreich?

Lösung

Der Punkt über C ++ / CLI ist korrekt. Um das Bild abzurunden, nur zwei weitere interessante Punkte:

  • .NET Speicherverwaltung (Garbage Collector) ist offensichtlich nicht das Problem hier, wie NMath noch davon abhängt

  • Der Leistungsvorteil wird von Intel MKL tatsächlich zur Verfügung gestellt, die Implementierungen extrem optimiert für viele CPUs bietet. Aus meiner Sicht ist dies der entscheidende Punkt. Mit straight-forward, naiv C / C ++ Code wird nicht unbedingt geben Sie eine überlegene Leistung über C # /. NET, manchmal ist es noch schlimmer. Jedoch C ++ / CLI können Sie alle "schmutzigen" Optimierungsmöglichkeiten nutzen.

Andere Tipps

  

Wie kann sie das tun?

Wie die meisten der numerischen Bibliotheken für .NET, ist NMath wenig mehr als ein Wrapper über einen Intel MKL in .NET Assembly eingebettet, wahrscheinlich durch die Verknüpfung mit C ++ / CLI einen gemischte Montage . Sie haben wahrscheinlich nur jene Bits gebenchmarkt, die in .NET nicht tatsächlich geschrieben werden.

Die F # .NET Zeitschriftenartikel Numerische Bibliotheken: Sonderfunktionen, Interpolation und Zufallszahlen (16. März 2008) und Numerische Bibliotheken: lineare Algebra und Spektralmethoden (16. April 2008) getestet einiges an Funktionalität und NMath war eigentlich die langsamste aller kommerziellen Bibliotheken. Ihre PRNG war langsamer als alle anderen und 50% langsamer als die freie Math.NET Bibliothek, einige grundlegende Funktionalität fehlte (zum Beispiel die Fähigkeit, Gamma(-0.5) zu berechnen) und andere grundlegende Funktionalität (die Gamma-bezogene Funktionen bieten sie tat) gebrochen war. Beide Extreme Optimierung und Bluebit schlagen NMath am eigensolver Benchmark. NMath nicht einmal ein Fourier-Transformation in der Zeit liefern.

Noch überraschender waren die Performance-Unterschiede manchmal sehr groß. Die teuerste kommerzielle numerische Bibliothek, die wir getestet (IMSL) war über 500 × langsamer als die freie FFTW Bibliothek an dem FFT-Benchmark und kein der Bibliotheken zur Zeit jegliche Verwendung von mehreren Kernen hergestellt.

In der Tat war es gerade die schlechte Qualität dieser Bibliotheken, die uns ermutigt, unseren eigenen zu kommerzialisieren F # für Numerik Bibliothek (die 100% reines F # -Code ist).

Ich bin einer der führenden Entwickler von ILNumerics . So bin ich voreingenommen, natürlich;) Aber wir sind unsere Interna offenbart in Bezug auf, so dass ich einige Einblicke in unsere Geschwindigkeit ‚Geheimnisse‘ geben.

Es hängt alles davon ab, wie Systemressourcen genutzt werden! Wenn Sie reine Geschwindigkeit und große Arrays umgehen müssen, werden Sie sicherstellen, dass auf (Reihenfolge nach Wichtigkeit, wichtigste zuerst)

  1. Verwalten Sie Ihre Speicher entsprechend! ‚Naive‘ Speicherverwaltung wird auf schlechte Leistung führen, da es die GC schlecht betont, Speicherfragmentierung verursacht und verschlechtert Speicherlokalizität (daher die Cache-Leistung). In einer Umgebung wie Müll gesammelt .NET, Furunkel dies von häufigen Speicherzuordnungen zu verhindern, nach unten. In ILNumerics, haben wir einen Hochleistungs-Speicher-Pool, um dieses Ziel zu archieve (und deterministische Entsorgung von temporären Arrays, die eine schöne, komfortable Syntax ohne plump Funktion Semantik zu erhalten).

  2. Nutzen Sie Parallelität! Dies richtet sich sowohl: Thread-Ebene Parallelität und Datenebene Parallelität. Mehrere Kerne werden durch Einfädeln rechenintensive Teile der Berechnung verwendet. Auf X86 / X64 CPUs SIMD / Multimedia-Erweiterungen wie SSE.XX und AVX ermöglichen, eine kleine, aber wirksame Vektorisierung. Sie werden nicht direkt von aktuellen .NET-Sprachen adressierbar. Und das ist der einzige Grund, warum MKL kann, ist immer noch schneller als ‚reiner‘ .NET-Code. (Aber Lösungen sind bereits gestiegen.)

  3. die Geschwindigkeit von hoch optimierten Sprachen wie Fortran und C ++, die gleichen Optimierungen, um Ihren Code bekommen angewandt müssen für sie getan. C # bietet die Möglichkeit, so tun.

Beachten Sie, sollten diese Vorsichtsmaßnahmen in dieser Reihenfolge beachten! Es macht keinen Sinn, über SSE-Erweiterungen oder sogar gebundene Kontroll Entfernung zu sorgen, wenn der Engpass die Speicherbandbreite ist und der Prozessor (en) verbringt die meiste Zeit für neue Daten zu warten. Auch für viele einfache Operationen ist es nicht lohnt, auch von großen Anstrengungen zu investieren, um den allerletzten kleinen Maßstab bis zu Spitzenleistungen archieve! Betrachten Sie das gemeinsame Beispiel der LAPACK Funktion DAXPY. Es fügt die Elemente eines Vektors X an das entsprechende Element von einem anderen Vektor Y. Wenn dies zum ersten Mal durchgeführt wird, werden alle der Speicher für X und Y werden abgerufen aus dem Hauptspeicher zu bekommen. Es gibt wenig bis nichts, was man dagegen tun kann. Und die Erinnerung ist der Engpass! Also unabhängig davon, ob die Zugabe am Ende wird die naive Art und Weise in C # getan

for (int i = 0; i < C.Length; i++) {
    C[i] = X[i] + Y[i]; 
}

oder durch Verwendung Vektorisierung Strategien getan - es muss für Speicher warten!

Ich weiß, diese Antwort macht irgendwie ‚über Antworten‘ die Frage, da die meisten dieser Strategien zur Zeit nicht aus dem genannten Produkt verwendet (noch?). Durch folgende thoses Punkte, würden Sie schließlich mit vielen besseren Leistung als jede naive Implementierung in einer ‚native‘ Sprache enden.

Wenn Sie interessiert sind, können Sie Ihre Implementierung von L-BFGS offenbaren? Ich werde glücklich sein es zu ILNumerics zu konvertieren und Vergleichsergebnisse posten und ich bin sicher, andere Bibliotheken hier aufgeführten möchten folgen. (?)

Ich habe einen Blog gepostet Artikel diese Frage Adressieren .

Der Schlüssel ist, C ++ / CLI . Es ermöglicht Ihnen, C ++ Code in einer verwalteten .NET-Assembly.

zu kompilieren

Heute ist es Industriestandard gemischte .Net / native Bibliotheken zu machen, um die Vorteile beiden Plattformen für die Performance-Optimierung zu nehmen. Nicht nur NMath, viele kommerzielle und freie Bibliotheken mit .NET-Schnittstelle wie diese arbeiten. Zum Beispiel: Math.NET Numerics, dnAnalytics , Extreme Optimierung, FinMath und viele andere. Integration mit MKL ist sehr beliebt für .net numerische Bibliotheken, und die meisten von ihnen verwenden nur C ++ Montage als Zwischenebene verwaltet. Aber diese Lösung hat eine Reihe von Nachteilen auf:

  1. Intel MKL ist eine proprietäre Software und es ist ein bisschen teuer. Aber einige Bibliotheken wie dnAnalytics bietet einen kostenlosen Austausch der MKL-Funktionalität mit reinem .NET-Code. Off Natürlich ist es viel langsamer, aber es ist kostenlos und voll funktionsfähig.

  2. Es reduziert Ihre Kompatibilität Sie schweren Managed C ++ Kernel-DLLs sowohl für 32-Bit- und 64-Bit-Modus.

  3. haben müssen
  4. Verwaltet nativen Anrufe Serialisieren müssen die Durchführung der Verlangsamung Leistung schnell häufig verwendete Operationen wie Gamma oder normalcdf.

Die letzten beiden in RTMath FinMath Bibliothek Probleme gelöst. Ich weiß wirklich nicht, wie sie es taten, aber sie bieten einzelne reine .net dll, die für jede CPU-Plattform kompiliert und unterstützt 32-Bit und 64-Bit. Auch habe ich keine Leistungsverschlechterung gegen MKL gesehen, als ich Milliarden mal anrufen müssen normalcdf.

Da die (nativ) Intel MKL Mathe tut, Sie tun wirklich nicht die Mathematik in verwaltetem Code. Sie sind lediglich die Speichermanager von .NET, so dass die Ergebnisse leicht von .NET-Code verwendet werden.

habe ich gelernt, mehr Form @Darin Dimitroffs Kommentar zu seiner Antwort und @Trevor Misfeldt Kommentar zu @ Darins Kommentar. Daher es als Antwort veröffentlichen, für zukünftige Leser.

NMath verwendet P / Invoke oder C ++ / CLI Intel Math Kernel Library native Funktionen aufrufen, die ist, wo die intensivste Berechnungen fertig sind und weshalb es so schnell ist.

Die Zeit ausgegeben in Zerlegungsmethoden innerhalb der Intel MKL . Kein Kopieren von Daten ist erforderlich , entweder. Also, es ist nicht eine Frage, ob CLI ist schnell oder nicht. Es geht darum, wo die Ausführung geschieht .

Auch @ Paul Blog ist auch ein gutes Buch. Hier ist die Zusammenfassung.

C # schnell ist, ist die Speicherzuordnung nicht. Reuse die Variablen als ref- oder out-Parameter , statt neue Variablen von Methoden zurückzukehren. eine neue Variable Zuteilen verbraucht Speicher und Ausführung verlangsamt. @Haymo Kutschbach hat dies gut erklärt.

Wenn die Genauigkeit nicht erforderlich ist, die Leistungssteigerung von doppelt auf einfache Genauigkeit bei der Umstellung beträchtlich ist (nicht den Speicher für die Datenspeicherung Speicher ganz zu schweigen).

Für viele kurze Berechnungen, eine C ++ / cli Routine von C # zu nennen, alle Zeiger auf Daten in dem verwalteten Raum zugewiesen Pinning, und rufen Sie dann die Intel-Bibliothek ist in der Regel besser als P mit / Invoke die Bibliothek direkt von C # nennen aufgrund der Kosten der Datenmarshalling. Wie bereits erwähnt von @Haymo Kutschbach in den Kommentaren, für blitfähig Typen jedoch kein Unterschied zwischen C ++ / CLI und C #. Arrays von blitfähig Typen und Klassen, die nur blitfähig Mitglieder enthalten, werden anstelle von kopiert gepinnt während Marshalling. Siehe https://msdn.microsoft.com/en -US / library / 75dwhxf7 (v = vs.110) aspx für eine Liste von blitfähig und nicht-blitfähig Typen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top