使用Matlab进行多线程编程

6
我正在进行一项与Matlab相关的项目,需要对性能进行优化。我考虑将从.m文件中调用的几个函数并行化。
这个想法很简单,从一个Matlab文件(.m)调用编译为MEX的C文件,从那个C文件创建一些线程,并从每个线程中回调Matlab函数。
理论上可行,我可以创建线程,也可以调用Matlab函数,但问题在于我无法从线程中调用Matlab函数。
//Global variables
mxArray **g_plhs;
mxArray **g_prhs;
int g_nlhs;
int g_nrhs;

//Thread function
DWORD WINAPI my_function( LPVOID lpParam ) 
{
    mexCallMATLAB(g_nlhs,g_plhs,g_nrhs,g_prhs,"matlab_function");
    return 0; 
}


//Main function
void mexFunction(int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[]) {

    DWORD dwThreadIdArray[MAX_THREADS];
    HANDLE  hThreadArray[MAX_THREADS]; 
    g_plhs = plhs;
    g_prhs = prhs;
    g_nlhs = nlhs;
    g_nrhs = nrhs;

    hThreadArray[0] = CreateThread( 
        NULL,                   
        0,                      
        my_function,            
        NULL,                   
        0,                      
        &dwThreadIdArray[0]);   

    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

    for(i=0; i<MAX_THREADS; i++)
    {
        CloseHandle(hThreadArray[i]);
    }
}

在使用matlab时,对这个选项有什么限制吗?有人尝试过类似的操作吗?

编辑:是否有不需要Parallel Toolbox的选项?


你想要并行化哪段MATLAB代码? - You
2
@rlbisbe:MEX API 不支持多线程:http://www.mathworks.com/support/solutions/en/data/1-V3B5T/index.html?solution=1-V3B5T - Amro
4个回答

6

您只能从MATLAB主线程调用mx*和mex*函数。如果要编写多线程MEX文件,必须确保它们在mx接口以下的级别上工作。如果您想要多个MATLAB解释器,则需要多个MATLAB进程。可以通过Parallel Computing Toolbox来实现,如@You所指出的那样。这将为您提供PARFOR循环和SPMD块以同时运行多个任务。


没有并行计算工具箱,还有其他选择吗? - Roberto Luis Bisbé
1
@rlbisbe:这里有一个使用OpenMP并行化代码的例子(只要您不从生成的线程中调用MEX API函数):http://www.walkingrandomly.com/?p=1795(还可以查看评论以获取建议的PCT替代方案) - Amro

3

您最好使用MATLAB内置的多线程功能,例如parfor。实际上,许多MATLAB函数已经是多线程的(包括矩阵运算),因此除了将for替换为parfor之外,您不需要自己并行化任何东西。(一般来说,while循环不能被并行化。)


2
Parfor需要Matlab并行工具箱,而我的Matlab许可证上没有它。 - Roberto Luis Bisbé

1

你最好的选择是使用parfor。如果你是学生,可以以相对便宜的价格获得并行工具箱。即使你认真考虑性能,全价也不算太贵。上面的代码容易出错且难以测试。使用parfor是直观和简洁的。


2
你的回答与5小时前You发布的回答有何不同?请确保你的回答实质性。如果你只是说并行工具箱很便宜,最好将其作为评论写在You的回答下面。 - user616736
哈哈,确实,这与You或Edric的答案并没有太大区别。感谢您指出这一点。 - brown.2179

1

我很惊讶大家都在推崇parfor。我建议您至少考虑一下是否可以设计您的算法,使其能够从Matlab调用并在多线程C/C++中运行关键部分而不需要回调到mex。这通常是可能的。特别是如果您使用Matlab profiler或类似工具来确定分析的哪些步骤是瓶颈,那么您可能只需编写1或2个步骤的多线程C代码。

另一种方法是在Java中编写并行处理,这在Matlab中更容易使用。

你可能想要查看其他选项,包括 Matlab Central上的multicore提交 或者 MatlabMPI。这两个选项都有点笨重,并且设计用于进程间并行(需要运行多个 Matlab 实例),因此不适合非常细粒度、复杂的并行计算。但是,如果只是将一个作业分成 4、8 或 16 部分,它们应该能够完成任务,至少 multicore 有合理的社区支持。我还没有尝试过 MatlabMPI,但它看起来很有前途。另外,这些选项应该可以跨多台机器工作,尽管它们可能需要共享网络文件系统。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接