我观察到以下与单元阵列有关的奇怪问题。我目前正在使用Matlab R2013a。请考虑以下代码。
#include <iostream>
#include <vector>
#include <chrono>
#include <mex.h>
#undef printf // to undo redefinition of printf by mex.h
#include <matrix.h>
void mexFunction(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs) {
if (nrhs != 0) {
mexErrMsgIdAndTxt("CellArray:InvalidInput", "There are too many input arguments required no of input args = 0");
}
if (nlhs != 1) {
mexErrMsgIdAndTxt("CellArray:InvalidOutput", "Incorrect number of output arguments required no of output args = 1");
}
int CellArrSize = 50820; // Number is prime
int CellContentSizeCurr = 1;
int CurrentCell = 732;
mwSize CellArrayDims[] = { CellArrSize, 1 };
std::vector<int *> IntArrayofArrays(CellArrSize, nullptr);
std::vector<int> CellContentSize(CellArrSize);
plhs[0] = mxCreateCellArray(2, CellArrayDims);
// Filling the Array of Arrays with the content to output
// into the cell array
for (int i = 0; i < CellArrSize; ++i) {
CellContentSizeCurr = (CellContentSizeCurr * 398) % 431; // 431 is primes
#ifdef IS_CONTIG
CurrentCell = i;
#else
CurrentCell = ((CurrentCell + 1) * 732) % 50821 - 1;
#endif
IntArrayofArrays[CurrentCell] = reinterpret_cast<int *>(mxCalloc(CellContentSizeCurr, sizeof(int)));
for (int j = 0; j < CellContentSizeCurr; ++j) {
IntArrayofArrays[CurrentCell][j] = i * CellContentSizeCurr + j;
}
CellContentSize[CurrentCell] = CellContentSizeCurr;
}
// Performing output of the Array of Array into Cell array
// (along with profiling code)
int TimeTakeninus = 0;
for (int i = 0; i < CellArrSize; ++i) {
mxArray * tempmxArray;
mwSize mxArrayDims[] = { 0,0 };
tempmxArray = mxCreateNumericArray(2, mxArrayDims, mxINT32_CLASS, mxREAL);
mxSetM(tempmxArray, CellContentSize[i]);
mxSetN(tempmxArray, 1);
auto TimeBeg = std::chrono::system_clock::now();
mxSetData(tempmxArray, IntArrayofArrays[i]);
auto TimeEnd = std::chrono::system_clock::now();
TimeTakeninus += std::chrono::duration_cast<std::chrono::microseconds>(TimeEnd - TimeBeg).count();
mxSetCell(plhs[0], i, tempmxArray);
}
mexPrintf("The time taken to perform output = %d ms\n", TimeTakeninus / 1000);
mexEvalString("drawnow");
}
有一个选项(define)IS_CONTIG
,它基本上决定了连续数组中的内存
IntArrayofArrays`是否连续分配。选择上面的数字即使在
在不连续的情况下,从0到大小为1的所有单元格索引都被填充(并分配)了一次。
MATLAB方面很简单
FinalCellArray = MexCellArrayTest();
观察到的问题如下
请注意,输出是使用mxSetData函数给出的(原则上) 只复制IntArrayofArrays [i]传递给它的内存位置的地址。
为什么会有很大差异?