Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么不';当使用MATLAB编译器时,我看到了显著的加速吗?_C_Performance_Matlab_Matlab Compiler - Fatal编程技术网

C 为什么不';当使用MATLAB编译器时,我看到了显著的加速吗?

C 为什么不';当使用MATLAB编译器时,我看到了显著的加速吗?,c,performance,matlab,matlab-compiler,C,Performance,Matlab,Matlab Compiler,我有很多很好的MATLAB代码,它们运行得太慢,用C写起来会很痛苦。C语言的MATLAB编译器似乎没有多大帮助,如果有的话。是否应该加快执行速度?我完蛋了吗?根据我的经验,缓慢的MATLAB代码通常来自于没有对代码进行矢量化(即,编写循环而不是仅仅乘法数组(简单示例)) 如果您正在进行文件I/O,请注意一次读取一块数据。在帮助文件中查找fscanf的矢量化版本 不要忘记,MATLAB也包括一个分析器 对于Matlab编译器,您可能指的是命令mcc,它通过绕过Matlab解释器,确实会稍微加快代码

我有很多很好的MATLAB代码,它们运行得太慢,用C写起来会很痛苦。C语言的MATLAB编译器似乎没有多大帮助,如果有的话。是否应该加快执行速度?我完蛋了吗?

根据我的经验,缓慢的MATLAB代码通常来自于没有对代码进行矢量化(即,编写循环而不是仅仅乘法数组(简单示例))

如果您正在进行文件I/O,请注意一次读取一块数据。在帮助文件中查找fscanf的矢量化版本


不要忘记,MATLAB也包括一个分析器

对于Matlab编译器,您可能指的是命令mcc,它通过绕过Matlab解释器,确实会稍微加快代码的速度。使用mex命令编译的实际C代码可以显著提高MAtlab代码的速度(提高50-200倍)。

我将附和dwj的说法:如果您的MAtlab代码速度慢,可能是因为它没有足够的矢量化。如果你在做显式循环,而你可以在整个数组上做操作,那就是罪魁祸首


这同样适用于所有面向数组的动态语言:Perl数据语言、数值Python、MATLAB/Octave等。在某种程度上,在编译的C和FORTRAN编译代码中也是如此:专门设计的矢量化库通常使用精心编写的内部循环和SIMD指令(例如MMX、SSE、AltiVec).

正如其他人所指出的,缓慢的Matlab代码通常是矢量化不足的结果

然而,有时即使是完全矢量化的代码也很慢。然后,您还有几个选项:

  • 查看是否有可以使用的库/工具箱。这些通常被写得非常优化
  • 分析您的代码,找出其中的难点,然后用普通C语言重写。将C代码(例如DLL)连接到Matlab很容易,文档中已经介绍了这一点
  • 如果您使用的是(在最新版本的MATLAB上),那么几乎肯定不会看到任何加速。这是因为编译器实际上只提供了一种打包代码的方法,这样就可以将代码分发给没有MATLAB的人。它不会将其转换为更快的代码(如机器代码或C)-它只是将其包装为C,以便您可以调用它

    它通过让您的代码在MATLAB编译器运行时(MCR)上运行来实现这一点,MCR本质上是MATLAB计算内核——您的代码仍在被解释。由于必须调用MCR而产生的惩罚,您可能会发现编译后的代码运行速度比在MATLAB上运行要慢

    换句话说,你可以说编译器实际上并没有编译,至少在传统意义上是这样

    较旧版本的编译器工作方式不同,在某些情况下可能会出现加速。对于Mathwork,让我们来看看


    mcc根本不会提高代码的速度——它不是真正的编译器

    在您放弃之前,您需要运行探查器,并弄清楚您的时间都花在哪里(工具->打开探查器)。此外,明智地使用“tic”和“toc”也会有所帮助。不要优化你的代码,直到你知道时间在哪里(不要试图猜测)

    请记住,在matlab中:

    • 位级操作非常慢
    • 文件I/O速度慢
    • 循环通常很慢,但矢量化很快(如果您不知道矢量语法,请学习它)
    • 核心运算速度非常快(例如矩阵乘法、fft)
    • 如果您认为可以在C/Fortran/etc中更快地完成某些事情,那么可以编写一个MEX文件
    • 有一些商业解决方案可以将matlab转换为C(谷歌“matlab-to-C”),它们可以工作

    首先,我支持上面关于分析和矢量化的所有评论

    从历史的角度来看

    旧版本的Matlab允许用户通过预解析m代码并将其转换为一组Matlab库调用,将m文件转换为mex函数。这些调用具有解释器执行的所有错误检查功能,但是解释器和/或在线解析器的旧版本速度较慢,因此编译m文件有时会有所帮助。通常,当你有循环时,它会有所帮助,因为Matlab足够聪明,可以在C中内联一些循环。如果你有Matlab的其中一个版本,你可以试着告诉mex脚本保存.C文件,你可以确切地看到它在做什么


    在最近的版本中(可能是2006a及更高版本,但我不记得了),Mathworks开始为解释器使用即时编译器。实际上,这个JIT编译器会自动编译所有mex函数,所以显式地脱机编译根本没有帮助。从那时起,在每一个版本中,他们都投入了大量的精力来提高解释器的速度。我相信新版本的Matlab甚至不允许您自动将m文件编译为mex文件,因为它不再有意义了。

    您尝试过分析代码吗?您不需要对所有代码进行矢量化,只需要对控制运行时间的函数进行矢量化。MATLAB分析器将为您提供一些提示,说明代码在哪里花费的时间最多


    在MathWorks手册的这一节中,您还应该阅读许多其他内容。

    您可以将代码移植到“嵌入式Matlab”,然后使用实时研讨会将其翻译为C

    嵌入式Matlab是Matlab的一个子集。它不支持单元阵列、图形、动态大小的矩阵或某些矩阵寻址模式。移植到嵌入式Matlab可能需要相当大的努力


    实时研讨会是代码生成产品的核心。它提供了通用的C语言,或者可以针对一系列嵌入式平台进行优化。您最感兴趣的可能是xPC目标,它将通用硬件视为嵌入式目标。

    MATLAB编译器包装您的m代码并将其发送到MATLAB运行时。所以
    s = [];
    for i = 1:50000
      s(i) = 3;
    end
    
    s = zeros(50000,1);
    for i = 1:50000
      s(i) = 3;
    end