MEX-функции часто могут улучшать производительность путем управления, когда функция делает копии больших массивов данных. Можно избежать ненужных копий массивов в этих случаях:
MEX-функция получает доступ к входному массиву, но элементы массива не изменяются.
MEX-функция изменяет входной массив, и измененный массив возвращен в функцию вызова.
Это MEX-функции суммируют элементы входного массива, но не изменяют массив. Присвоение inputs[0] к
переменной matlab::data::TypedArray<double> const позволяет вам использовать основанный на области значений цикл for, чтобы суммировать элементы. При определении массива, когда const гарантирует, что переменный inArray остается разделяемым с входным массивом.
#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<double> inArray = inputs[0];
for (auto& elem : inArray) {
sm += elem;
}
outputs[0] = factory.createScalar(sm);
}
};После сохранения этого кода в файле (названный addArrayElements.cpp в этом примере), скомпилируйте его с функцией mex. Вызовите эту MEX-функцию от MATLAB® с двойным массивом как входной параметр.
mex addArrayElements.cpp
b = addArrayElements([1:1e7]);
b =
5.0000e+13Эта MEX-функция заменяет отрицательные величины во входном массиве с нулями. Эта операция изменяет входной массив, таким образом, входной параметр не может остаться разделяемым с измененным массивом. После проверки входного массива функция не использует inputs[0] снова. Поэтому подтвержденный массив inputs[0] перемещен в переменную matlab::data::TypedArray<double>, чтобы позволить использованию основанного на области значений цикла for изменить элементы массива.
Чтобы предотвратить копию входного массива, переместите input[0] в matlab::data::TypedArray<double> с помощью std::move(), который подкачивает память, сопоставленную с входным массивом к переменному 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<double> 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") }));
}
}
};После сохранения этого кода в файле (названный removeNegativeNumbers.cpp в этом примере), скомпилируйте его с функцией mex.
mex removeNegativeNumbers.cpp
Вызовите эту MEX-функцию от функции MATLAB. Повторно присвойте измененный массив той же переменной.
function arry = processArray(arry) arry = removeNegativeNumbers(arry); .... end
Например, вызовите функцию processArray с большим массивом, возвращенным функцией randn MATLAB.
A = processArray(randn(10000));
min(A(:))
ans =
0