matlab-mex-c++:在 for 循环中,为数组分配非常量值很慢

matlab-mex-c++: in a for loop, It's slow to assign a non-constant value to an array

本文关键字:非常 分配 常量 数组 for 循环 matlab-mex-c++      更新时间:2023-10-16

我尝试使用matlab mex(c++)来优化我的matlab程序。问题是给数组赋值(不是常量)非常慢。我自己找不到答案。

背景:

c++源代码如下:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ ...
    int row_num = 6000, col_num=4000;
    int total_sim_num=row_num*row_num, total_rate_num=row_num*col_num;
    plhs[0] = mxCreateNumericMatrix(row_num, row_num, mxSINGLE_CLASS, mxREAL);
    //plhs[0] is the pointer of output matrix, and, indeed, it's an 1-D vector.
    //Matlab code can use it as 2-D matrix.
    float* out_mat = (float*)mxGetData(plhs[0]);
    //later, I want to write the calculated value to matrix: out_mat

这是一个3层循环,输出矩阵很大:a_OUT=row_num*row_num

结果取决于一些输入矩阵:A_IN=row_num*col_num。

for(int u=0; u<row_num; u++)
{
    for(int v=u, vx=0; v<total_sim_num; v+=row_num, vx++)
    {
        for (int i=u, ix=vx; i<total_rate_num; i+=row_num, ix+=row_num)
        {
            float calculated_value = ix/row_num;  //it's fast.
            out_mat[v] = calculated_value;  //It's very slow (~ 10 minutes)
                                            //out_mat[v] -> A_OUT[u][v] 
            out_mat[v] = 2;  //assign constant, it's fast (< 2 seconds)                     
        }
    }
}

如评论中所述:

  1. 将常量指定给out_mat是快速的
  2. 将计算值分配给局部变量很快
  3. 为out_mat指定计算值的速度非常慢

我也试过这个:

float* testv = new float[total_sim_num];

然后:

testv[v] = calculated_value; //It's very slow too.

有人能分享为什么在为out_mat指定计算值时速度如此缓慢的原因吗?是否可以像为out_mat指定常量一样快?

非常感谢!

Jun

在写入out_mat时,使用多个不同值(在第三级循环中按顺序计算)覆盖同一数组元素(out_mat[v],其中v是第二级for-循环的控制变量)。

所以,当你只给数组分配常量时,编译器可能会优化对第二级循环的分配,也可能会完全优化掉第三级循环。

你确定你粘贴在这里的代码是对的吗?

MATLAB矩阵按列顺序存储。您正在创建的mxArrayrow_num x row_num,可能应该是row_num x col_num

然后,您应该使用i + (j-1)*row_numout_mat数组进行索引,以访问i行和j列。