In place array flipping - mex in place

7 vues (au cours des 30 derniers jours)
Jim Hokanson
Jim Hokanson le 6 Mar 2015
Modifié(e) : James Tursa le 9 Mar 2015
I'm trying to flip a large vector and I noticed that Matlab is not doing this in place. More on how I know this in a bit. Is it possible to write a mex function with an output that will functionally allow an inplace manipulation.
In other words, if I write:
x = myMexFunction(x)
will the pointers for the input and output ever match?
Note, the alternative is to do:
myMexFunction(x)
where I modify x inside the mex function, in-place, but this is discouraged, see this great article and especially the comments:
I'm also open to other ways of doing this.
A bit of background on doing this in Matlab.
If I do the following, I see a constant oscillation in the allocated memory as determined by Windows Task Manager.
y1 = 1:1e8;
while true
y1 = y1(end:-1:1);
pause(0.1)
end
To me it seems like once I do the initial allocation of y1, this function should never need more memory. Instead the memory usage is fluctuating suggesting constant allocation and deallocation of a temporary variable.
It is perhaps interesting to note that Matlab recently (past couple of years) introduced a function called flip() which fliplr and flipud now call. This seems to be more memory efficient but still causes unneeded memory allocation.
EDIT: I tried this again and it seemed to be in place, perhaps it is just not guaranteed but can be in place. Any clarification from someone who knows better would be appreciated: END EDIT
while true
y1 = flip(y1,1);
pause(0.1)
end
The alternative approach that I would like to do is the following (roughly):
n_in = floor(length(y1)/2);
len_p1 = length(y1)+1;
for iSample = 1:n_in
end__sample = len_p1-iSample;
t1 = y1(iSample);
y1(iSample) = y1(end__sample);
y1(end__sample) = t1;
end
The idea is to swap the first and last samples, then move inwards, all done in place.
Thoughts? Suggestions?
Thanks, Jim

Réponses (1)

James Tursa
James Tursa le 6 Mar 2015
Modifié(e) : James Tursa le 9 Mar 2015
Unless TMW officially documents this, I think you are stuck with your explicit loop approach. If TMW documents the in-place rules for this function, then they are committing themselves to maintaining this and testing it with each release (or at least tell you when the rules changes). Without that documentation, they can change the behavior at any time with no notice.
Regarding mex-in-place programming, this is basically impossible to do safely with standard API functions since TMW supplies no method to determine when a variable is shared. So one has to resort to undocumented methods (e.g., your link). To complicate matters, there are various forms of sharing ... some forms are easy to detect and others are very difficult. E.g., the various forms of sharing that I am aware of are (nomenclature is my own since there is no official documentation for much of this)
Shared Data Copy:
Two different variables, with two different physical variable structures in memory, share the same data pointers. Easy to detect in a mex routine by hacking into the variable structure and examining the CrossLink pointer (NULL means it is not shared, non-NULL means it is shared).
Shared Reference Copy:
Two different sub-elements (cell or struct array elements or object fields or properties) share the same variable structure (and consequently their data pointers as well). Easy to detect in a mex routine by hacking into the variable structure and examining the Reference Count field (0 means it is not a reference copy, non-0 means it is a reference copy).
Shared Parent Copy:
Two different sub-elements share the same variable structure through a parent chain. Near impossible to detect reliably in a mex routine. There are no indicators in the variable structure itself that tell you when a variable has common parent sharing with another variable. The only partial solution I am aware of is to use mexCallMATLAB with the "whos" command to get a list of everything in the workspace, then examine all of them to see if there is any parent sharing. Messy and maybe not reliable.
Handle Derived Class Variables:
These are classdef OOP objects derived from the handle class. Two different variables will have physically different variable structures but share the same data pointers. Storage wise very similar to Shared Data Copy but internally the CrossLink pointer is NULL and shared data copies are not made when the data changes. I haven't looked into how one can deal with these in a mex routine, although in general classdef OOP objects are very difficult to deal with in mex routines efficiently since the only official API functions that TMW supplies to access the properties, mxGetProperty and mxSetProperty, force deep data copies ... which pretty much cripples their use in mex routines if the variables are large.
Bottom line for mex programming in-place is that if the variable is not a sub-element (cell element or struct field or classdef object property), then you can reliably detect sharing in a mex routine and take appropriate steps to be safe in how you change it. If it is a sub-element, all bets are off.

Catégories

En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by