Main Content

升级 MEX 文件以使用 64 位 API

mex 命令默认使用 -largeArrayDims 选项。本主题描述如何升级 MEX 文件以使用 64 位 API。

您可以通过调用带有 -compatibleArrayDims 选项的 mex 命令继续使用 32 位 API。有关使用此选项的详细信息,请参阅What If I Do Not Upgrade?

要查看并更新 MEX 文件的源代码,请使用以下检查清单。

  1. 在编辑之前准备代码 - 请参阅备份文件并创建测试

  2. 以迭代方式更改和测试代码。

    在使用 64 位 API 编译 MEX 文件之前,请使用更新变量重构您的现有代码。对于 Fortran,则使用Upgrade Fortran MEX Files to use 64-bit API 重构您的代码。

    每次更改后,请编译并测试您的代码:

  3. 使用 64 位 API 进行编译。要编译 myMexFile.c,请键入:

    mex myMexFile.c

  4. 消除故障和警告 - 请参阅解决 -largeArrayDims 编译故障和警告

  5. 比较结果 - 请参阅执行 64 位 MEX 文件并与 32 位版本的结果进行比较

  6. 检查内存 - 请参阅使用大型数组进行试验

以下过程使用 C/C++ 术语和示例代码。Fortran MEX 文件存在相同的问题,需要执行Upgrade Fortran MEX Files to use 64-bit API中所述的更多任务。

备份文件并创建测试

在修改代码之前,确认 MEX 文件可与 32 位 API 结合使用。至少构建预期的输入和输出列表,或创建完整的测试套件。使用这些测试,将结果与更新后的源代码进行比较。结果应该相同。

备份所有源、二进制和测试文件。

更新变量

要处理大型数组,请转换包含数组索引或大小的变量,以使用 mwSizemwIndex 类型,而不是 32 位 int 类型。查看您的代码是否包含以下变量类型:

更新用于调用 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)

输入参量 mn 的类型为 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);

mxCreateDoubleMatrixmxCreateStructMatrix 的函数签名为:

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_tunsigned_int64 或其他类似的名称。

大多数编译问题都与 32 位和 64 位类型之间的类型不匹配有关。请参考 How do I update MEX-files to use the large array handling API (-largeArrayDims)? 中的步骤 5,了解特定编译器的常见编译问题及可能的解决方案。

执行 64 位 MEX 文件并与 32 位版本的结果进行比较

将使用 64 位 API 编译的 MEX 文件的运行结果与原始二进制文件的结果进行比较。如果存在任何差异或故障,请使用调试器调查原因。有关调试器功能的信息,请参阅您的编译器文档。

要确定在运行 MEX 文件时可能遇到的问题及可能的解决方案,请参考 How do I update MEX-files to use the large array handling API (-largeArrayDims)? 中的步骤 6。

在解决问题并升级您的 MEX 文件后,它将在使用大型数组处理 API 的同时复制原始代码的功能。

使用大型数组进行试验

如果您可以访问具有大内存量的计算机,则可以使用大型数组进行试验。一个包含 232 个元素的双精度浮点数数组(MATLAB 中的默认值)需要占用大约 32 GB 的内存。

有关演示大型数组用法的示例,请参阅Handling Large mxArrays in C MEX Files 中的 arraySize.c MEX 文件。

相关示例

详细信息

外部网站