Matlab: Führt das wiederholte Aufrufen der gleichen mex-Funktion in einer Schleife zu viel Aufwand?

8

Ich habe Matlab-Code, der beschleunigt werden muss. Durch das Profiling habe ich eine bestimmte Funktion als Ursache für die Verlangsamung der Ausführung identifiziert. Diese Funktion wird innerhalb einer Schleife hunderttausende Male aufgerufen.

Mein erster Gedanke war, die Funktion in mex zu konvertieren (mit Matlab Coder), um sie zu beschleunigen. Der allgemeine Programmiersinn sagt mir jedoch, dass die Schnittstelle zwischen Matlab und dem mex-Code zu einem gewissen Mehraufwand führen würde, was bedeutet, dass das Anrufen dieser mex-Funktion tausende von Malen keine gute Idee ist. Ist das richtig? Oder macht Matlab Magie, wenn immer wieder das gleiche Geld gerufen wird, um den Overhead zu entfernen?

Wenn ein signifikanter Overhead ist, denke ich darüber nach, den Code so umzuformatieren, dass die Schleife der Funktion selbst hinzugefügt wird und dann ein Ergebnis davon erzeugt. Bevor ich das tue, möchte ich meine Annahme bestätigen, um die dafür aufgewendete Zeit zu rechtfertigen.

Aktualisierung:

Ich habe @ Angainors Vorschlag versucht und doningothing.m mit dem folgenden Code erstellt:

%Vor%

Dann habe ich eine mex-Funktion daraus als donothing_mex erstellt und den folgenden Code ausprobiert:

%Vor%

Das Ergebnis war, dass eine Million Aufrufe an die Funktion ungefähr 9 Sekunden dauerte. Dies ist kein bedeutender Overhead für unsere Zwecke, daher denke ich, dass ich die aufgerufene Funktion erst einmal zu mex konvertieren werde. Allerdings scheint eine Funktion aus einer Schleife, die ungefähr eine Million Mal ausgeführt wird, im Nachhinein eine ziemlich dumme Idee zu sein, wenn man bedenkt, dass dies performance-kritischer Code ist, so dass die Schleife zur mex-Funktion noch in den Büchern ist, aber mit viel geringerer Priorität.

    
sundar 16.10.2012, 19:03
quelle

3 Antworten

5

Wie immer hängt alles von der Menge an Arbeit ab, die Sie in der MEX-Datei tun. Der Aufwand für den Aufruf der MEX-Funktion ist konstant und hängt nicht von der Problemgröße ab. Das bedeutet, dass Argumente in nicht in neue temporäre Arrays kopiert werden. Wenn es genug Arbeit ist, wird der MATLAB-Overhead des Aufrufs der MEX-Datei daher nicht angezeigt. Wie auch immer, meiner Erfahrung nach ist der MEX-Aufruf-Overhead nur beim ersten Aufruf der mex-Funktion von Bedeutung - die dynamische Bibliothek muss geladen, Symbole aufgelöst werden usw. Nachfolgende MEX-Aufrufe haben sehr wenig Aufwand und sind sehr effizient.

Fast alles in MATLAB ist aufgrund der Natur dieser Hochsprache mit einem Overhead verbunden. Es sei denn, Sie haben einen Code, von dem Sie sicher sind, dass er vollständig mit JIT kompiliert ist (aber Sie brauchen dann keine mex-Datei :)) Sie haben also die Wahl zwischen einem Overhead und dem anderen.

Also zusammenfassend - ich hätte keine Angst davor, dass MEX Overhead ruft.

Bearbeiten Wie oft hier und an anderen Stellen zu hören, ist das einzig Vernünftige in jedem Fall natürlich BENCHMARK und überprüfen Sie es selbst. Sie können den MEX-Aufruf-Overhead leicht schätzen, indem Sie eine triviale MEX-Funktion schreiben:

%Vor%

Auf meinem Computer bekommen Sie

%Vor%

Das ist 2e-6s Overhead pro MEX-Aufruf. Fügen Sie Ihren Code hinzu, geben Sie Zeit ein und sehen Sie, ob der Overhead auf einem akzeptablen Level ist oder nicht.

Wie Andrew Janke unten bemerkt (danke!), hängt der Overhead der MEX-Funktion offenbar von der Anzahl der Argumente ab, die Sie an die MEX-Funktion übergeben. Es ist eine kleine Abhängigkeit, aber es ist da:

%Vor%

Es hängt nicht mit der Größe von a zusammen:

%Vor%

Aber es hängt mit der Anzahl der Argumente zusammen

%Vor%

Sie sollten dies bei Ihren Tests berücksichtigen.

    
angainor 16.10.2012, 19:09
quelle
2

Sie sollten unbedingt die Schleife innerhalb der mex Datei verschieben. Das folgende Beispiel zeigt eine 1000-fache Beschleunigung für eine praktisch leere Arbeitseinheit in einer for-Schleife. Offensichtlich wird sich die Geschwindigkeit verringern, wenn sich der Arbeitsaufwand in der for-Schleife ändert.

Hier ist ein Beispiel für den Unterschied:

Mex-Funktion ohne interne Schleife:

%Vor%

In Matlab aufgerufen:

%Vor%

Mex-Funktion mit interner Schleife:

%Vor%

In Matlab aufgerufen:

%Vor%     
twerdster 17.10.2012 07:53
quelle
2

Nun, das ist der schnellste, den ich in Matlab machen kann:

%Vor%

Können Sie das kompilieren und einige Tests durchführen? (Aus irgendeinem seltsamen Grund funktioniert die Kompilierung bei meiner Installation nicht ...) Vielleicht ändere %#eml in %#codegen zuerst, wenn du denkst, dass das einfacher ist.

HINWEIS: Für die C-Version sollten Sie auch die for-Schleifen austauschen, so dass die Schleife über j die innere ist.

Auch der Ansatz row1 und row2 ist viel speichereffizienter. Wenn Sie trotzdem kompilieren, würde ich diesen Ansatz verwenden.

    
Rody Oldenhuis 18.10.2012 09:01
quelle

Tags und Links