Laden...

Unmanaged code möglichst schnell aufrufen

Erstellt von marcom vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.326 Views
M
marcom Themenstarter:in
123 Beiträge seit 2007
vor 16 Jahren
Unmanaged code möglichst schnell aufrufen

Hallo zusammen,

ich möchte aus C# möglichst schnell unmanaged code (in einer C DLL) aufrufen. Im moment sehe ich da zwei Möglichkeiten:
a) ganz normal über p/invoke über static extern...

b) mit LoadLibrary und GetProcAddress die Adresse eines Funktionszeigers holen und diesen dann mit der Marshal Klasse in ein delegate umwandeln.

So rein vom Gefühl her würde ich sagen, dass der zweite Ansatz schneller ist, da man zu jedem Zeitpunkt ein delegate schon hat und man den nur aufrufen muss während bei der ersten Variante die DLL gegebenfalls noch geladen werden muss (wird sie sofort nach dem Funktionsaufruf wieder entladen?)

Seht ihr noch andere Möglichkeiten? Bei der aufzurufenden Funktion handelt es sich um eine PaintFunktion die eben recht oft (ohne Parametern und Rückgabewert) aufgerufen wird.

Danke und Grüße,

Mark

871 Beiträge seit 2005
vor 16 Jahren

Hallo,

ich würde sagen Du entwickelst einfach mal zu testzwecken alle beiden Varianten und führst anschliessend Benchmarks durch, dann siehst Du was schneller ist (ich persönlich denke dass es Variante 2 sein wird)

Grüsse,
Egon

343 Beiträge seit 2007
vor 16 Jahren

Falls du so einen Benchmark durchführst bitte posten, wäre da selbst gespannt.

Mfg
Preli

[- www.saftware.net -](http://www.saftware.net/)
S
8.746 Beiträge seit 2005
vor 16 Jahren

Die Performance läßt sich auch noch steigern, indem man den Pinvoke-Deklaration mittels SuppressUnmanagedCodeSecurityAttribute auszeichnet. Damit verzichtet .NET einen StackTrace aufzubauen und auf SecurityAttribute zu prüfen. Allerdings wird das ganze dann unsafe Code.

871 Beiträge seit 2005
vor 16 Jahren

Hallo,

ich hab mir grade einen Micro-Benchmark geschrieben der das ganze testet. Und ich bin überascht:* LoadLibrary, GetProcAddress und Marshall nach Delegate: Für 1.000.000 Calls 279 ms (Mit Über- und Rückgabewert: 294 ms)

  • P/Invoke (Standard): Für 1.000.000 Calls: 49 ms (Mit Über- und Rückgabewert: 45ms)
  • P/Invoke (SuppressUnmanagedCodeSecurity): Für 1.000.000 Calls: 4 ms (Mit Über- und Rückgabewert: Stack Overflow....)

Hätt ich ehrlich gesagt nicht gedacht. Anbei der Micro-Benchmark.

Grüsse,
Egon

M
marcom Themenstarter:in
123 Beiträge seit 2007
vor 16 Jahren

Hi Egon,

danke für Deine Ergebnisse! Sehr interessant!!
Also ist mal wieder der einfache Weg schneller 🙂

Gibt es eine Möglichkeit, zur Laufzeit den Modulnamen (DLL Namen) sowie Einsprungnamen zu setzen (wenn man mittels P/Invoke arbeitet) oder ist das eben der Preis für die Geschwindigkeit ?

871 Beiträge seit 2005
vor 16 Jahren

Hallo,

out-of-the Box gibts so was nicht so weit ich weiss - Du könntest aber System.Reflection.Emit bemühen um dir zur Laufzeit was entsprechendes zusammen zu bauen.

Grüsse,
Egon

V
86 Beiträge seit 2008
vor 16 Jahren

Nur rein interessehalber:
Wie ruft man managed C++ Code am schnellsten auf?
Mir schien es am schnellsten wenn ich eine Verlinkung über Referenz meines Projekts auf das C++ Projekt zugreife und es normal wie jede andere Klasse aufrufe. Ist das richtig?
Ich glaub deswegen muss ich jetzt nicht unbedingt nen neuen Thread aufmachen 😉.

Ah, und noch was zum Thema, wäre es viel langsamer wenn ich eine Wrapper Klasse erstelle und diese wie oben geschrieben aufrufe?

2.760 Beiträge seit 2006
vor 16 Jahren

wie jede andere Klasse aufrufe

Nichts anderes ist es.
Managed C++ oder C++/CLI generiert ja auch nur ein Assembly. Ist also so als ob du in einem Projekt C# und VB.Net mischst, da am ende immer IL-Code rauskommt solltest du die Dll ganz normal als Referenz anbinden schneller und kompatibler gehts wohl kaum...