升级 MEX 文件以使用 64 位 API
mex 命令默认使用 -largeArrayDims 选项。本主题描述如何升级 MEX 文件以使用 64 位 API。
您可以通过调用带有 -compatibleArrayDims 选项的 mex 命令继续使用 32 位 API。有关使用此选项的详细信息,请参阅What If I Do Not Upgrade?。
要查看并更新 MEX 文件的源代码,请使用以下检查清单。
在编辑之前准备代码 - 请参阅备份文件并创建测试。
以迭代方式更改和测试代码。
在使用 64 位 API 编译 MEX 文件之前,请使用更新变量重构您的现有代码。对于 Fortran,则使用Upgrade Fortran MEX Files to use 64-bit API 重构您的代码。
每次更改后,请编译并测试您的代码:
使用 32 位 API 进行编译。例如,要编译 myMexFile.c,请键入:
mex -compatibleArrayDims myMexFile.c
使用 64 位 API 进行编译。要编译 myMexFile.c,请键入:
mex myMexFile.c
检查内存 - 请参阅使用大型数组进行试验。
以下过程使用 C/C++ 术语和示例代码。Fortran MEX 文件存在相同的问题,需要执行Upgrade Fortran MEX Files to use 64-bit API中所述的更多任务。备份文件并创建测试
在修改代码之前,确认 MEX 文件可与 32 位 API 结合使用。至少构建预期的输入和输出列表,或创建完整的测试套件。使用这些测试,将结果与更新后的源代码进行比较。结果应该相同。
备份所有源、二进制和测试文件。更新变量
要处理大型数组,请转换包含数组索引或大小的变量,以使用 mwSize 和 mwIndex 类型,而不是 32 位 int 类型。查看您的代码是否包含以下变量类型:
矩阵 API 函数直接使用的变量 - 请参阅更新用于调用 64 位 API 函数的参数。
用作大小/索引值和用作 32 位整数的变量 - 请参阅分析其他变量。更新用于调用 64 位 API 函数的参数
识别代码中使用 mwSize / mwIndex 类型的 64 位 API 函数。有关函数列表,请参阅Using the 64-Bit API。搜索您用于调用函数的变量。检查函数参考文档的语法标题下面显示的函数签名。该签名确定了取 mwSize / mwIndex 值作为输入值或输出值的变量。更改您的变量以使用正确的类型。
例如,假设您的代码使用以下语句中所示的 mxCreateDoubleMatrix 函数:
int nrows,ncolumns;
...
y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);
要查看函数签名,请键入:
doc mxCreateDoubleMatrix
签名为:
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n,
mxComplexity ComplexFlag)
输入参数 m 和 n 的类型为 mwSize。如表中所示更改代码。
替换:为:int nrows,ncolumns;mwSize nrows,ncolumns;更新用于数组索引和大小的变量
如果您的代码使用中间变量来计算大小和索引值,请将 mwSize / mwIndex 用于这些变量。例如,以下代码将 mxCreateDoubleMatrix 的输入声明为 mwSize 类型:
mwSize nrows,ncolumns;/* inputs to mxCreateDoubleMatrix */
int numDataPoints;
nrows = 3;
numDataPoints = nrows * 2;
ncolumns = numDataPoints + 1;
...
y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);
该示例使用中间变量 numDataPoints(类型为 int)来计算 ncolumns 的值。如果您将 nrows 中的 64 位值复制到 32 位变量 numDataPoints,则结果值将被截断。您的 MEX 文件可能崩溃或产生错误的结果。如下表中所示,将类型 mwSize 用于 numDataPoints。
替换:为:int numDataPoints;mwSize numDataPoints;分析其他变量
您无需更改代码中的每个整数变量。例如,结构体和状态代码中的字段编号为 int 类型。不过,您需要识别用于多种用途的变量,必要时将其替换为多个变量。
以下示例将基于传感器的数量创建矩阵 myNumeric 和结构体 myStruct。该代码将一个变量 numSensors 同时用于数组大小和结构体中的字段数量。
mxArray *myNumeric, *myStruct;
int numSensors;
mwSize m, n;
char **fieldnames;
...
myNumeric = mxCreateDoubleMatrix(numSensors, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensors, fieldnames);
mxCreateDoubleMatrix 和 mxCreateStructMatrix 的函数签名为:
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n,
mxComplexity ComplexFlag)
mxArray *mxCreateStructMatrix(mwSize m, mwSize n,
int nfields, const char **fieldnames);
对于 mxCreateDoubleMatrix 函数,您的代码将 numSensors 用于变量 m。m 的类型为 mwSize。对于 mxCreateStructMatrix 函数,您的代码将 numSensors 用于变量 nfields。nfields 的类型为 int。要处理这两个函数,请将 numSensors 替换为两个新变量,如下表所示。
替换:为:int numSensors;/* create 2 variables */
/* of different types */
mwSize numSensorSize;
int numSensorFields;
myNumeric =
mxCreateDoubleMatrix(
numSensors,
n, mxREAL);/* use mwSize variable */
/* numSensorSize */
myNumeric =
mxCreateDoubleMatrix(
numSensorSize,
n, mxREAL);
myStruct =
mxCreateStructMatrix(
m, n,
numSensors,
fieldnames);/* use int variable */
/* numSensorFields */
myStruct =
mxCreateStructMatrix(
m, n,
numSensorFields,
fieldnames);在每个重构迭代后进行测试、调试并解决存在的差异
要使用 32 位 API 编译 myMexFile.c,请键入:
mex -compatibleArrayDims myMexFile.c
使用您在此过程开始时创建的测试,将更新的 MEX 文件的结果与原始二进制文件进行比较。两个 MEX 文件应返回相同的结果。否则,请调试并解决存在的任何差异。此时解决差异的难度比使用 64 位 API 编译时解决差异的难度要小。解决 -largeArrayDims 编译故障和警告
在查看并更新代码之后,使用大型数组处理 API 来编译 MEX 文件。要使用 64 位 API 编译 myMexFile.c,请键入:
mex myMexFile.c
由于 mwSize / mwIndex 类型为 MATLAB® 类型,因此您的编译器有时将其称为 size_t、unsigned_int64 或其他类似的名称。执行 64 位 MEX 文件并与 32 位版本的结果进行比较
将使用 64 位 API 编译的 MEX 文件的运行结果与原始二进制文件的结果进行比较。如果存在任何差异或故障,请使用调试器调查原因。有关调试器功能的信息,请参阅您的编译器文档。
在解决问题并升级您的 MEX 文件后,它将在使用大型数组处理 API 的同时复制原始代码的功能。使用大型数组进行试验
如果您可以访问具有大内存量的计算机,则可以使用大型数组进行试验。一个包含 232 个元素的双精度浮点数数组(MATLAB 中的默认值)需要占用大约 32 GB 的内存。
相关示例
详细信息
外部网站