Ich versuche, eine C ++ - Klasse in einen Matlab-Mex-Wrapper zu schreiben, indem ich den hier beschriebenen Ansatz hier verwende . Im Grunde habe ich eine Initialisierungs-Mex-Datei, die ein C ++ - Objekthandle zurückgibt:
%Vor% Ich kann das dann an eine andere mex-Datei übergeben (z. B. myclass_amethod
), die den Handle verwendet, um Klassenmethoden aufzurufen, und schließlich auf myclass_delete
, um das C ++ - Objekt freizugeben:
Ich habe dies in einer MATLAB-Klasse zusammengefasst, um die Benutzung zu vereinfachen:
%Vor% Dies funktioniert in nicht parallelem Code. Sobald ich es jedoch innerhalb von parfor
anrufe:
Ich erhalte einen segfault, da eine Kopie der Klasse in der parfor
-Schleife (in jedem Worker) erstellt wird, aber da jeder Worker ein separater Prozess ist, wird die C ++ - Objektinstanz nicht kopiert. führt zu einem ungültigen Zeiger.
Ich habe versucht, zunächst zu erkennen, wann jede Klassenmethode in einer parfor-Schleife ausgeführt wurde, und in diesen Fällen auch das C ++ - Objekt neu zuzuweisen. Da jedoch nicht überprüft werden kann, ob ein Objekt bereits für den aktuellen Worker zugewiesen wurde, führt dies zu mehreren Neuzuweisungen und dann nur einem Löschen (wenn der Worker beendet wird), was zu einem Speicherverlust führt (siehe Anhang im Frage für Details).
matlab.mixin.Copyable
In C ++ würde dies mit Kopierkonstruktoren geschehen (so dass das C ++ - Objekt nur einmal neu zugewiesen wird, wenn die Wrapper-MATLAB-Klasse kopiert wird). Eine Schnellsuche öffnet den matlab.mixin.Copyable -Klassen-Typ scheint die erforderliche Funktionalität bereitzustellen (dh tiefe Kopien von MATLAB-Handle-Klassen). Daher habe ich folgendes versucht:
%Vor%Testen dieser Klasse wie oben, d. h .:
%Vor%Ergebnisse in der Ausgabe:
%Vor%Mit anderen Worten, scheint, dass der Kopierkonstruktor nicht aufgerufen wird, wenn er workers für das parfor erzeugt. Hat jemand irgendwelche Hinweise, was ich falsch mache, oder ob es eine Möglichkeit gibt, das gewünschte Verhalten der Reinitialisierung des C ++ - Objekt-Handles zu erreichen, wenn die MATLAB-Wrapper-Klasse kopiert wird?
Nur zur Referenz: Hier ist der alternative Ansatz, den ich verwende, wenn ich in einem Worker neu zugewiesen werde:
%Vor%und die Ausgabe:
%Vor%Wie oben zu sehen ist, tritt tatsächlich eine Neuzuweisung auf, wenn ein Arbeiter ausgeführt wird. Der -Destruktor wird jedoch nur einmal für jeden Worker aufgerufen, unabhängig davon, wie lange die C ++ - Klasse neu zugeordnet wurde, was zu einem Speicherverlust führte.
loadobj
Folgendes funktioniert:
%Vor% Wenn Sie eine Objektinstanz in den Körper einer PARFOR
-Schleife übergeben, verhält sich das Verhalten so, als ob Sie es in einer Datei gespeichert und dann erneut geladen hätten. Die einfachste Lösung ist wahrscheinlich, Ihre cpp_handle_
als Transient
zu markieren. Dann müssen Sie SAVEOBJ
und LOADOBJ
implementieren, um Ihre Daten sicher zu transportieren. Weitere Informationen zum Anpassen des Speicher- / Ladeverhaltens Ihrer Klasse finden Sie auf dieser Seite .
Tags und Links matlab oop parallel-processing copy-constructor mex