Avoid Copies of Arrays in MEX Functions - MATLAB & Simulink (original) (raw)
Main Content
MEX functions often can improve performance by controlling when the function makes copies of large data arrays. You can avoid unnecessary copies of arrays in these cases:
- The MEX function accesses an input array, but the elements of the array are not modified.
- The MEX function modifies an input array and the modified array is returned to the calling function.
If you are writing MATLABĀ® code instead of C++ applications, see Avoid Unnecessary Copies of Data.
Input Array Not Modified
This MEX function sums the elements of the input array, but does not modify the array. Assigning inputs[0]
to a const
matlab::data::TypedArray variable lets you use a range-based for
loop to sum the elements. Specifying the array as const
ensures the variableinArray
remains shared with the input array.
#include "mex.hpp" #include "mexAdapter.hpp"
using namespace matlab::data; using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function { ArrayFactory factory; public: void operator()(ArgumentList outputs, ArgumentList inputs) { double sm = 0; const TypedArray inArray = inputs[0]; for (auto& elem : inArray) { sm += elem; } outputs[0] = factory.createScalar(sm); } };
After saving this code in a file (called addArrayElements.cpp
in this example), compile it with the mex function. Call this MEX function from MATLAB with a double array as the input argument.
mex addArrayElements.cpp b = addArrayElements([1:1e7]); b =
5.0000e+13
Input Array Modified
This MEX function replaces negative values in the input array with zeros. This operation modifies the input array so the input cannot remain shared with the modified array. After validating the input array, the function does not useinputs[0]
again. Therefore, the validatedinputs[0]
array is moved to a matlab::data::TypedArray variable to enable the use of a range-based for
loop to modify the array elements.
To prevent a copy of the input array, move input[0]
to a matlab::data::TypedArray using std::move()
, which swaps the memory associated with the input array to the variable largeArray
.
#include "mex.hpp" #include "mexAdapter.hpp"
using namespace matlab::data; using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function { public: void operator()(ArgumentList outputs, ArgumentList inputs) { checkArguments(inputs); TypedArray largeArray = std::move(inputs[0]); for (auto& elem : largeArray) { if (elem < 0) { elem = 0; } } outputs[0] = largeArray; }
void checkArguments(ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE) {
matlabPtr->feval(u"error", 0,
std::vector<Array>({ factory.createScalar("Incorrect input") }));
}
}
};
After saving this code in a file (calledremoveNegativeNumbers.cpp
in this example), compile it with the mex function.
mex removeNegativeNumbers.cpp
Call this MEX function from a MATLAB function. Reassign the modified array to the same variable.
function arry = processArray(arry) arry = removeNegativeNumbers(arry); .... end
For example, call the processArray
function with a large array returned by the MATLABrandn function.
A = processArray(randn(10000)); min(A(:))
ans =
0