性能权衡 – 何时MATLAB比C / C ++更好/更慢?
我知道C / C ++是一种低级语言,当与其他任何高级语言进行比较时,会生成相对优化的机器码。 但是我觉得还有不止这些,从实践中也可以看出来。
当我做一些简单的计算,如高斯样本集的蒙特卡洛平均等等时,我发现C ++实现和MATLAB实现之间没有什么区别,有时实际上MATLAB在时间上performance得好一些。
当我使用数千行代码进行更大规模的模拟时,慢慢地显示出真实的图像。 C ++仿真显示出优越的性能,比时间复杂度比同等的MATLAB实现要好100倍。
C ++中的代码大部分都是串行的,没有明确的hi-fi优化。 而根据我的意识,MATLAB固有地做了很多优化。 例如,当我尝试生成大量的随机样本时,在C ++中使用像IT ++ / GSL / Boost这样的库执行相对较慢的操作(所使用的algorithm与mt19937相同)。
我的问题是简单地知道在MATLAB / C ++之间是否有一个简单的权衡。 难道就像人们所说的:“只要有可能,C / C ++就更好”(经验丰富的)。 从另一个angular度来看,“除了舒适之外,MATLAB还有什么好处呢?”
顺便说一句,在这里我没有看到编码效率参数是重要的,在这两种情况下,想到同一个程序员。 而且,我认为像Python,R这样的其他select在这里是不相关的。 但是依赖于我们使用的特定的库应该是有趣的。
[我是通信系统编码理论的博士生。 我一直在用matlab / C ++进行仿真,并且在两种情况下都有合理的编码几行10K的经验]
我已经使用Matlab和C ++大约10年了。 对于我的研究中实现的每个数值algorithm,我总是从Matlab原型开始,然后将项目翻译成C ++,以获得10倍到100倍(我不是开玩笑)的性能改进。 当然,我正在比较优化的C ++代码与完全vector化的Matlab代码。 平均而言,改善幅度约为50倍。
两种编程语言背后都有很多微妙之处,下面是一些误解:
-
Matlab是一种脚本语言,但是C ++被编译
Matlab使用JIT编译器将您的脚本转换为机器码,通过使用Matlab提供的编译器,您可以将速度提高1.5倍至2倍。
-
Matlab代码可能能够完全向量化,但是你必须在C ++中手工优化你的代码
完全vector化的Matlab代码可以调用用C ++ / C / Assembly(例如Intel MKL)编写的库。 但是简单的C ++代码可以通过现代编译器进行合理的vector化。
-
Matlab提供的工具箱和例程应该被很好地调整,并且应该具有合理的性能
除了线性代数例程之外,其性能通常很差。
与vector化Matlab代码相比,您可以在C ++中获得10倍〜100倍的性能:
-
在Matlab中调用外部库(MKL)需要花费时间。
-
Matlab中的内存是dynamic分配和释放的。 例如,小matrix乘法:
A = B*C + D*E + F*G
需要Matlab来创build2个临时matrix。 而在C ++中,如果你事先分配你的内存,你创buildNONE。 现在想象一下你循环1000次的声明。 C ++中的另一个解决scheme是由C ++ 11 Rvalue引用提供的。 这是C ++中最大的改进之一,现在的C ++代码可以和普通的C代码一样快。 -
如果要进行并行处理,Matlab模型是多进程的,C ++的方式是multithreading的。 如果你有许多小任务需要并行化,C ++提供线性增益到multithreading,但你可能在Matlab中有负性能增益。
-
你在C ++中通过引用传递大对象,大量内存,但在Matlab中相当棘手。
-
C ++中的vector化涉及使用内在函数/汇编,有时SIMDvector化只能在C ++中实现。
-
指针在C ++中创造奇迹。 成像交换两个matrixA和B:在Matlab中,它涉及第三matrix,并且需要3 * N * N个基本复制操作。 但在C ++中,这是通过成本接近零的指针完成的。
-
在C ++中,经验丰富的程序员可以完全避免L2高速caching未命中,甚至L1高速caching未命中,从而将CPU推到理论上的吞吐量限制。 由于这个原因,Matlab的性能可能落后于C ++ 10倍。
-
在C ++中,计算密集型指令有时可以根据它们的等待时间(在汇编或内部函数中谨慎编码)和依赖性(大部分时间由编译器或CPU硬件自动完成)进行分组,这样理论IPC(每个时钟周期的指令)到达和CPUpipe道被填满。
但是,与Matlab相比,C ++的开发时间也是10倍!
你应该使用Matlab而不是C ++的原因:
-
数据可视化。 我认为我的职业生涯可以不用C ++,但是如果没有Matlab就无法生存,因为它可以产生美丽的情节!
-
低效率,但在math上强大的内置例程和工具箱。 先得到正确的答案,然后谈论效率。 人们可以在C ++中犯下微妙的错误(例如隐式地将double转换为int )并得到正确的结果。
-
expression你的想法,并向同事展示你的代码。 Matlab代码比C ++更容易阅读,并且比C ++更短,并且可以在没有编译器的情况下正确执行Matlab代码。 我只是拒绝阅读其他人的C ++代码。 我甚至不使用C ++ GNU科学库,因为代码质量不能保证。 研究人员/工程师使用C ++库作为黑箱是非常危险的,并且准确无误。 即使对于商业化的C / C ++库,我记得去年英特尔编译器在其sin()函数中有一个符号错误,在MKL中也出现了数值准确性问题。
最后但是同样重要的:
因为一旦Matlab代码被vector化了,程序员就没有太多的工作要做,所以与C ++代码相比,Matlab代码的性能对代码质量的敏感度要低得多。 因此,最好在Matlab中优化计算algorithm,稍好的algorithm在Matlab中通常具有稍好的性能。 另一方面,用C ++进行algorithmtesting需要相当程序员用相同的方式编写或多或less优化的algorithm,以确保编译器不会对algorithm进行不同的优化。
根据我的经验(几年计算机视觉和两种语言的image processing),对于这个问题没有简单的答案,因为Matlab的性能在编码风格上强烈地依赖于C ++(而不仅仅是性能)。
通常,Matlab包装了经典的基于C ++ / Fortran的线性代数库。 所以,像x = A\b
这样的东西会非常快。 此外,Matlab在为这些types的问题select最有效的求解器方面做得很好,所以对于x = A\b
Matlab将会查看matrix的大小并select合适的低级例程。
如果你“向量化”了你的代码,也就是说如果你避免for
循环并且使用索引数组或者布尔数组访问你的数据,那么Matlab也会在大数据matrix的数据操作中发光。 这东西是高度优化的。
对于其他例程,有些是用Matlab代码编写的,有些则指向C / C ++实现(例如Delaunay的东西)。 你可以通过inputedit some_routine.m
来检查。 这将打开代码,你会看到它是全部的Matlab还是只是编译的东西的包装。
Matlab认为,主要是为了舒适性,但是舒适度转化为编码时间,最终是金钱,这就是为什么在业界使用Matlab。 另外,对于除计算机科学以外的其他领域的工程师来说,很容易学习,而且在编程方面的培训很less。
作为博士生,还有一个10年的Matlab用户,我很高兴能分享我的POV:
Matlab是开发和原型algorithm的一个很好的工具,特别是在处理graphics用户界面(GUI),高级分析(频域,LS优化等)时:快速编码,强大的语法(想想[],{},:等等)。
只要你的处理链更加稳定和定义,数据维数增长到C / C ++。
当考虑到语言的脚本时,主要的Matlab限制上升:只要避免任何cicle(使用arrayfun,cellfun或其他matrix过程),由于被调用子程序又是在C / C ++中,性能很高。
Matlab在线性代数和arrays/matrix运算方面做得非常好,因为他们似乎在底层操作上做了一些额外的优化 – 如果你想在那里打败Matlab,你需要一个类似优化的BLAS / LAPACK库。
作为一种解释型语言,由于内部开销,Matlab每当调用Matlab函数时就会失去时间,传统上这意味着Matlab循环很慢。 近几年来,由于JIT编译器的重大改进(例如,在MATLAB上search“性能”问题),这已经有所缓解。 由于函数调用的开销,所有在C / C ++后台都没有实现的Matlab函数(调用edit functionName
来查看它是否用Matlab编写)的风险比C / C ++相对要慢。
最后,Matlab试图用户友好,并可能做“不必要”的input检查,可能需要时间(由于函数调用开销)。 例如,如果您知道ismember
获得sorting的input,则可以直接调用ismembc
(幕后编译函数),节省相当多的时间。
你的问题很难回答。 一般而言,C ++速度更快,但如果使用Matlab写得很好的algorithm,则可以超越C ++。 在某些情况下,Matlab可以并行处理你的代码,这在C ++的许多情况下必须手动完成。 Mathlab可以输出C ++代码。
所以我的结论是,你必须衡量两个scheme的performance才能得到答案。 但是,你比较你的两个实现,而不是一般的Matlab和C ++。
我想你至less可以考虑四倍的差距。
- 编译与解释
- 强types与dynamictypes
- 性能与快速原型
- 特别的力量
对于1-3可以很容易地推广到两种编程语言族之间的比较。
对于4, MATLAB
针对matrix运算进行了优化。 所以,如果你能在MATLAB
vector化更多的代码,性能可以大大提高。 相反,如果需要多个loops
,请不要犹豫使用C++
或创build一个mex
文件。
毕竟这是一个困难的问题。
除了最后一个程序的速度外,还应该考虑到代码的总开发时间,即不仅要写时间,还要考虑到debugging等。Matlab(及其开放源代码的Octave )由于其可视化function,可以很好地进行快速原型devise。
如果你使用的是直接的C ++(即没有matrix库),那么编写与Matlab代码相当的C ++代码可能需要更长的时间(例如,花费10个小时编写仅运行10秒的C ++代码就没有意义了比起花5分钟写出来的Matlab程序更快)。
但是,还有专门的C ++matrix库,如Armadillo ,它提供了一个类似Matlab的API。 这对编写可从Matlab调用的性能关键代码或将Matlab代码转换为“真实”程序非常有用。
从MATLAB切换到C ++时,我看到了5.5倍的速度提升。 这是一个机器人控制器 – 很多循环和颂歌解决。 我花了好几个小时来试图优化MATLAB代码,几乎没有时间优化C ++(我相信它可以多花一点时间快10倍)。
但是,为MATLAB代码添加一个GUI很容易,所以我仍然经常使用它。 像其他人所说的那样,在MATLAB上首先进行原型开发是很好的。 这使得在C ++上的实现更加简单。
一些Matlab代码使用内置multithreading的标准线性代数小说。 所以,看起来他们比顺序的C代码更快。