在Matlab中加速mex文件

在Matlab中加速mex文件,matlab,Matlab,我有一个大循环,我需要在我的代码中计算很多次,我认为使用MATLABcoder可以加速它。但是,我的代码的mex文件版本(函数的代码附在下面)最终比m文件慢。我使用MINGW64编译器编译了代码 我尝试了不同的编译器设置(使用coder.config)和不同的内存规范,但没有成功 function v_d = test_code(q,v_exp,wealth,b_grid_choice,k_grid_choice,nz,nk,nb) %#codegen % Inputs % q is a

我有一个大循环,我需要在我的代码中计算很多次,我认为使用MATLABcoder可以加速它。但是,我的代码的mex文件版本(函数的代码附在下面)最终比m文件慢。我使用MINGW64编译器编译了代码

我尝试了不同的编译器设置(使用coder.config)和不同的内存规范,但没有成功

function    v_d = test_code(q,v_exp,wealth,b_grid_choice,k_grid_choice,nz,nk,nb)
%#codegen

% Inputs
% q is an array of dimension [nz nk nb]
% v_exp is an array of dimension [nz nk nb]
% wealth is an array of dimension [nz nk nb]
% b_grid_choice is an array of dimension [nk nb]
% k_grid_choice is an array of dimension [nk nb]
% Typically, nz/nk/nb is an integer (currently up to 200)

v_d = coder.nullcopy(zeros(nz,nk,nb));

    parfor ii = 1:nz          
            q_ini_ii = reshape(q(ii,:,:),[],nz);
            v_ini_exp_ii = reshape(v_exp(ii,:,:),[],nz); 
            choice = q_ini_ii.*b_grid_choice - k_grid_choice;

            for jj = 1:nk
                for kk = 1:nb 
                    % dividends at time t
                    d =  wealth(ii,jj,kk)  + choice;
                    % choosing optimal consumption
                    vec_d = d + v_ini_exp_ii.*(d>0);
                    v_d(ii,jj,kk) = max(vec_d,[],'all'); 
                end
            end
    end
当我在
nz
=
nk
=
nb
=
100
运行此代码时,m文件需要2.5s,而生成的mex文件需要7.5s。我尝试使用MATLABcoder应用程序和
codegen
命令

codegen -O enable:OpenMP test_code -args {q,v_exp,wealth,b_grid_choice,k_grid_choice,nz,nk,nb}
我还玩了
codegen.config('mex')
,但对性能影响不大



当我测试上述代码的速度时,我只需使用
randn
命令生成这些矩阵,然后将它们传递到代码中。有趣的是,当我在函数中生成这些矩阵时,这对m文件的速度没有影响,但会将mex文件的速度提高近10倍(因此比m文件快3倍)!这对我来说意味着有一种方法可以加快代码的速度,但是尽管我努力了,我还是没能找到它。我认为内存分配可能是背后的原因,但我尝试使用动态内存规范也没有带来任何收益

为了加快代码的速度,将循环转过来:内部循环应该在第一个索引上,外部循环应该在最后一个索引上。这将按存储顺序处理数据,从而优化缓存使用。此外,手动编写的MEX文件可能比
codegen
生成的文件快。@CrisLuengo感谢您的建议。不幸的是,更改循环顺序并没有提高性能。我想加快速度的唯一方法是在C++中编写这段代码,然后编译它而不是依赖于代码。这个代码是“大循环”还是这个函数经常被调用在“大循环”中?我不确定在mex函数中,
parfor
是否是一个好主意(我甚至不知道这是否有效…)。它可能会在每次调用该函数时设置一个新池,从而导致开销。MATLAB代码可能更快,因为并行池仍然是open@max这段代码是一个“大循环”,但在实际代码中,它将在一个while循环内。现在,我只是想用我正在加速的函数的一部分来学习一些关于mex文件的知识。据我所知,parfor在墨西哥工作。当我使用-O disable:OpenMP关闭它时,mex代码的速度会大大降低(我还看到task manager中的CPU利用率很低)。我明白你关于matlab池的观点,但是当测试池被打开时,我总是可以在运行代码之前为它设置一个计时器,以便在循环运行时打开它。要加快代码的速度,请将循环转过来:内循环应该在第一个索引上,外循环应该在最后一个索引上。这将按存储顺序处理数据,从而优化缓存使用。此外,手动编写的MEX文件可能比
codegen
生成的文件快。@CrisLuengo感谢您的建议。不幸的是,更改循环顺序并没有提高性能。我想加快速度的唯一方法是在C++中编写这段代码,然后编译它而不是依赖于代码。这个代码是“大循环”还是这个函数经常被调用在“大循环”中?我不确定在mex函数中,
parfor
是否是一个好主意(我甚至不知道这是否有效…)。它可能会在每次调用该函数时设置一个新池,从而导致开销。MATLAB代码可能更快,因为并行池仍然是open@max这段代码是一个“大循环”,但在实际代码中,它将在一个while循环内。现在,我只是想用我正在加速的函数的一部分来学习一些关于mex文件的知识。据我所知,parfor在墨西哥工作。当我使用-O disable:OpenMP关闭它时,mex代码的速度会大大降低(我还看到task manager中的CPU利用率很低)。我明白你关于matlab池的观点,但是当测试池被打开时,我总是可以在运行代码之前为它设置一个计时器,以便在循环运行时打开它。