Функции MEX часто могут повысить производительность, контролируя, когда функция создает копии больших массивов данных. В следующих случаях можно избежать ненужных копий массивов:
Функция MEX обращается к входному массиву, но элементы массива не изменяются.
Функция MEX изменяет входной массив, и измененный массив возвращается вызывающей функции.
Эта функция MEX суммирует элементы входного массива, но не изменяет массив. Назначение inputs[0] в const
matlab::data::TypedArray<double> переменная позволяет использовать диапазон 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 функция с большим массивом, возвращаемым MATLAB randn функция.
A = processArray(randn(10000));
min(A(:))
ans =
0