CLI kombiniert mit nativem C/C++



  • Hallo.

    Ich habe gelesen, dass C++/CLI deutlich langsamer ist als natives C++, da die Funtionen aus .NET erst zur Laufzeit kompiliert werden. Deshalb ist das Programm auch nur unter Windows lauffähig - damit kann ich leben.
    Es ist nun aber so, dass ich ein wissenschaftliches Programm geschrieben haben (in nativem C auf der Kommandozeile) und dieses nun neu schreiben- und dabei auch eine GUI für das Programm erstellen möchte. Nun bieten die .NET Bibliotheken ja tolle, vordefinierte Möglichkeiten und vor allem die Gestaltung von Fenstern ist super einfach und VC++ unterstützt auch OpenMPI.
    Nun meine Frage: Wenn ich nun darauf achte, die .NET Bibliotheken nur in der GUI, nicht aber in den Rechenalgorithmen (es geht um die Verarbeitung riesiger Datenmengen) nutze, laufen dann die Methoden zur Berechnung genauso schnell wie wenn ich alles in nativem C++ programmiere oder kann mir die Nutzung eines OpenFileDialogs zum Laden der Daten oder einer vordefinierten Form-Klasse die Performance in einer späteren, total unabhängigen Funktion (in nativem C (nicht C++) geschrieben), welche die geladenen Daten dann verarbeitet bereits verschlechtern? Es geht um die Lösung sehr großer Gleichungssysteme.

    Ich muss diese Frage leider stellen, bevor ich mich tiefer in VC++2010 einarbeite, da die Antwort dann festlegt, ob ich damit überhaupt weiter mache oder komplett auf CLI verzichte 😕 .

    Vielen Dank im Voraus,
    CJens.

    Ps.: Die Einleitung "VC++ ist nicht für GUI Programmierung geeignet" habe ich gelesen. Allerdings möchte ich in meiner Anwendung nur einfach Einstellungsmöglichkeiten bieten - zusätzlich brauche ich aber einen schnellen Code und ich möchte (später) auch mit OpenGL ein vordefiniertes Gitter in einerm Grafikfenster zeigen und rotieren lassen. Ich lasse mich zwar gerne vom Gegenteil überzeugen, doch schien mir dafür dann C++ doch die beste Lösung.



  • Ich glaub, du hast nicht ganz verstanden was C++/CLI ist. Ist aber nicht weiter schlimm, denn du solltest sowieso besser C# verwenden. Von allen Dingen ist GUI wohl so ziemlich das letzte, wofür C++/CLI zu empfehlen wäre. Alles, was wirklich C++ sein muss, kannst du in eine dll packen und diese von C# aus verwenden...und tu dir selbst einen Gefallen und verwend doch eine aktuelle Version von Visual Studio; du wirst sehen, dass Microsoft selbst alle Projektvorlagen für GUI Kram in C++/CLI mittlerweile aus Visual Studio entfernt hat; mehr braucht man dazu wohl kaum noch zu sagen... 😉



  • CJens schrieb:

    (in nativem C (nicht C++) geschrieben)

    Gerade das macht es doch einfach C# für die GUI zu nehmen. C# kann mit aus DLLs exportierten C-Funktionen umgehen. Eine existierende Kommandozeilenanwendung sollte man so einfach umbauen können. Komplizierter wäre es, wenn C++ Objekte zu .net weitergereicht werden müssten, nur innerhalb dieser Zwischenschicht wäre der einzige Anwendungsfall für C++/CLI.

    Anscheinend haben die meisten, die meinen "C++/CLI zu müssen", nicht verstanden, dass es in einer Visual Studio Projektmappe Projekte in mehreren Sprachen geben kann, und die auch nahtlos zusammenarbeiten.



  • Also die GUI in C# und die Methoden fürs Number-Crunching schreibe ich dann in C++ und packe die in eine statische Klasse, welche ich in C# dann einbinden kann.
    Kann man in C# auch OpenGL nutzen? Es geht um die Darstellung eines Gitternetzmodells (das Gitter lade ich ein, ich muss also keine Geometrie rendern - das Rendering wird extern erledigt)? Ich habe sowas mal mit DirectX unter Visual Basic Uralt gemacht und da ging das sehr einfach, wenn man die Elemente schon zur Verfügung hatte.



  • CJens schrieb:

    Also die GUI in C# und die Methoden fürs Number-Crunching schreibe ich dann in C++ und packe die in eine statische Klasse, welche ich in C# dann einbinden kann.

    Nope, du musst ein herkömmliches, prozedurales Interface basteln. DLLs unterstützen keine Klassen. Wenn du Klassen willst, musst du C++/CLI verwenden, um .NET Wrapper für deine nativen C++ Klassen zu basteln (das wäre dann zur Abwechslung genau der eine Anwendungsfall, für den C++/CLI konzipiert ist). Ich würde an deiner Stelle versuchen, das zu vermeiden.

    CJens schrieb:

    Kann man in C# auch OpenGL nutzen?

    Ja, gibt genug Wrapper Libraries dafür. Eine der atm populärsten ist wohl OpenTK. Hab ich aber selber noch nie verwendet. Meiner Erfahrung nach ist OpenGL in .NET extrem anstregend zu programmieren, da keine vernünftigen Mittel zur Ressourcenverwaltung zur Verfügung stehen. OpenGL ist, dank RAII, in C++ imo wesentlich angenehmer zu coden. Ich würde mir überlegen, das evtl. auch in die DLL zu packen...

    CJens schrieb:

    Es geht um die Darstellung eines Gitternetzmodells (das Gitter lade ich ein, ich muss also keine Geometrie rendern - das Rendering wird extern erledigt)?

    Bin mir nicht ganz sicher, wie genau du dir das vorstellst. OpenGL wird jedenfalls garantiert nicht von selbst irgendwas rendern. Evtl. willst du mal einen Blick auf WPF werfen, das hat rudimentäre Fuktionalität für 3D Rendering bereits eingebaut...



  • CJens schrieb:

    Ich habe gelesen, dass C++/CLI deutlich langsamer ist als natives C++, da die Funtionen aus .NET erst zur Laufzeit kompiliert werden.

    "Deutlich" - höchstens Faktor 2, und das auch nur dann, wenn du wirklich gut C++ kannst und optimalen Code schreibst.
    Versuch dein "Number Crunching" vielleicht erstmal auch in C# zu schreiben, wenn du das ganze eh neuschreibst. Wenn du merkst, dass es zu langsam ist, oder deutlich langsamer als dein ursprüngliches C Programm, dann kannst es vielleicht nochmal in C oder C++ schreiben. Aber sonst würde ich das ganze nicht zu kompliziert machen, wenn es nicht sein muss, und Wahrscheinlichkeit ist recht hoch, dass es nicht sein muss.



  • Mechanics schrieb:

    "Deutlich" - höchstens Faktor 2, und das auch nur dann, wenn du wirklich gut C++ kannst und optimalen Code schreibst.

    Das kann man so nicht sagen. C++/CLI erlaubt sowohl nativen als auch managed Code, die Aussage, dass C++/CLI langsamer wäre als C++ macht eigentlich überhaupt kaum Sinn. Ohne das konkrete Problem zu kennen, kann man nichtmal einen brauchbaren Schätzwert für den Einfluss irgendwelches hypothetischen Overhead angeben, mal ganz davon abgesehen, dass man mit solchen Schätzwerten in der Regel sowieso falsch liegt.

    Es stimmt, dass die Performance von C# für viele Dinge ausreichend ist, selbst mich hat das bereits einige Male überrascht. Ich würde aber mal davon ausgehen, dass es gute Gründe gibt, den fraglichen Code in C++ zu schreiben!?



  • Erstmal vielen vielen Dank für die Antworten. Hab mir jetzt ein Buch zu C# bestellt... und dann werde ich mir das wohl oder übel jetzt auch antun müssen.

    Eine Frage noch: Könnt ihr Literatur empfehlen zu DLLs? Hab jetzt ein erstes Beispiel mit

    extern "C"
    {
      __declspec(dllexport) void JensTestDLL()
      {
    }
    

    und

    [DllImport("JensLib.dll")]
    

    erstellt und es funktioniert aber mal ehrlich - ich habe keine Ahnung, warum es funktioniert. Das ist für mich echt chinesisch. Jetzt habe ich drei Bücher zu C++ und eines zu nativem C... nirgends kann ich diesen "extern" Befehl und die anderen finden. Ich werde den sicher ergoogeln können, aber ich würde auch gerne die Zusammenhänge verstehen.

    Danke Euch,
    CJens.

    Ps.: Es geht um die Lösung von sehr großen Gleichungssystemen (sehr groß bedeutet typischerweise 10 Mio. Gleichungen und 10 Mio. Unbekannte... da geht es wirklich um Geschwindigkeit - Faktor 2 ist ein Quantensprung...). Ich bin zwar noch kein absoluter Profi im HP-Computing, aber gerade das will ich auch lernen. So gesehen finde ich den Vorschlag, die Oberfläche in C# zu schreiben und den eigentlicher Solver-Algorithmus im nativem C sehr elegant.

    Für alle, die ein Beispiel dafür suchen:
    http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w



  • Viel mehr gibts da auch nicht zu wissen. Damit sagst du nur dem Compiler, dass die Funktion exportiert werden soll. Dlls haben eine Tabelle mit Funktionen, die sie exportieren. Wahnsinnig viel mehr Zusammenhänge gibts da auch nicht, da schreibt man keine Bücher drüber.

    Ist dein Algorithmus so komplex oder könntest du ihn probeweise und C und in C# implementieren? Mich würd hier echt mal interessieren, ob du mit C spürbar schneller bist. Ich selber hab noch nie performancekritische Anwendungen in C# geschrieben. Mich würde mal interessieren, wie gut der JIT Compiler von .NET hier optimieren kann, eigentlich müsste er sowas genauso gut wie der C++ Compiler optimieren können.
    Ich denke, wenn Faktor 2 für dich ein Quantensprung ist, wirst du grundsätzlich noch einiges optimieren können. Mehrere Threads, SSE, CUDA usw...



  • Wenn du derart große Gleichungssysteme mit guter Performance und Genauigkeit lösen willst, willst du in der Regel wohl eher irgendeine bewährte Numerikbibliothek verwenden und das auf keinen Fall selbst schreiben!?



  • ...also, der eigentliche Lösungsalgorithmus... das sind drei ineinander geschachtelte Schleifen... das ist am Ende ein 30-Zeiler.
    Da kann ich, wenn es so weit ist, mal nen Benchmark machen.

    Vielleicht kann der C#-Kompiler das auch gut übersetzen - viel muss er nicht machen - einfach in den Maschinencode übersetzen. In diesem Löser gibt man ihm über die Zeiger eigentlich alles vor. Über ein gutes Memory-Management muss man sich im Vorneherein Gedanken machen, um einen schnellen Zugriff zu erhalten. Kann man in C# auch auf einer sehr niedrigen Ebene arbeiten, also Einfluss darauf nehmen, wies die Elemente im Speicher liegen, wie es in C der Fall ist?

    Wir OpenMP unterstützt? Oder hat das Microsoft seine eigene Variante für Parallelisierung?



  • In dem Fall ist es sehr wahrscheinlich, dass du da auch mit C# ausreichend schnell, wenn nicht sogar praktisch gleich schnell bist...



  • ...welcher die Performance von C++ mit C# vergleicht.
    http://megos.wordpress.com/2009/06/06/die-performance-von-c-sharp-programmen/

    Sehr interessant ist ein Link zu einem Buch welches sich mit der Performancesteigerung bei C# beschäftigt:
    "Effective C#: 50 Specific Ways to Improve Your C#"

    Auch habe ich einen Weg gefunden, OpenMPI in C# über einen Umweg einzubauen.

    Resumet: Die wirklich rechenintensiven Methoden werde ich wohl in C++ schreiben und dann über DLL importieren, denn ich benötige bei solchen Gleichungssystemen (Matrizen) sehr viele Zugriffe auf die Daten - und es handelt sich dabei nicht um sequenzielle Zugriffe, so dass C# bei jedem Zugriff den Index intern prüfen würde. Gerade bei Gleichungslösern ist jedoch der Speicherzugriff das, was am meisten Zeit benötigt. Hier sind Numerikbibliotheken natürlich optimiert, aber ich will es einmal selbst machen - dann werde ich sicher auch auf Boost-Bibliothek oder ATLAS zurückgreifen.

    Aber mit C# kann man wohl doch vieles ohne den Einsatz von C++ schnell bearbeiten. Der Einsatz von OpenMPI begünstigt dies.



  • Willst du das Gleichungssystem dann auf einem Cluster lösen, oder wofür genau brauchst du MPI?



  • CJens schrieb:

    Sehr interessant ist ein Link zu einem Buch welches sich mit der Performancesteigerung bei C# beschäftigt:
    "Effective C#: 50 Specific Ways to Improve Your C#"

    In dem Buch geht es nicht um Performance, jedenfalls nicht primär. Nicht, dass du da mit falschen Hoffnungen herangehst...



  • dot schrieb:

    Willst du das Gleichungssystem dann auf einem Cluster lösen, oder wofür genau brauchst du MPI?

    Naja, lokalparallel. Ich will mich nicht zu tief in die Parallelisierung vertiefen, aber einfache Schleifen würde ich schon gerne Parallelisieren. Das geht ja mit Open MPI sehr schön.





  • Nur um das klarzustellen... Ich glaube, du meinst Open MP, nicht MPI.


Anmelden zum Antworten