问题描述
我知道 C/C++ 是一种低级语言,当我们与任何其他高级语言进行比较时,它会生成相对优化的机器代码.但我猜想的远不止这些,从实践中也可以看出这一点.
I am aware that C/C++ is a lower-level language and generates relatively optimized machine code when we compare with any other high-level language. But I guess there is pretty much more than that, which is also evident from the practice.
当我对高斯样本集合进行蒙特卡洛平均等简单计算时,我发现 C++ 实现或 MATLAB 实现之间没有太大区别,有时实际上 MATLAB 的性能在时间上要好一些.
When I do simple calculations like montecarlo averaging of a Gaussian sample collection or so, I see there is not much of a difference between a C++ implementation or MATLAB implementation, sometimes in fact MATLAB performs a bit better in time.
当我继续使用数千行代码进行更大规模的模拟时,慢慢地就会出现真实的画面.C++ 仿真显示出卓越的性能,在时间复杂度上比等效的 MATLAB 实现高 100 倍.
When I move on to larger scale simulations with thousands of lines of code, slowly the real picture shows up. C++ simulations show superior performance like 100x better in time complexity than an equivalent MATLAB implementation.
大多数情况下,C++ 中的代码几乎是连续的,并且没有明确进行高保真优化.然而,据我所知,MATLAB 本质上做了很多优化.例如,当我尝试生成大量随机样本时,就会出现这种情况,而在 C++ 中,使用 IT++/GSL/Boost 等库的等效项的执行速度相对较慢(使用的算法相同,即 mt19937).
The code in C++ most of the times, is pretty much serial and no hi-fi optimization is done explicitly. Whereas, as per my awareness, MATLAB inherently does a lot of optimization. This shows up for example when I try to generate a huge chunk of random samples, where as the equivalent in C++ using some library like IT++/GSL/Boost performs relatively slower (the algorithm used is the same namely mt19937).
我的问题只是想知道 MATLAB/C++ 在性能方面是否有更简单的权衡.是不是就像人们所说的无论何时,C/C++ 都是更好的"(经常经历的)?.换个角度看,除了舒适,MATLAB 还有什么好处?"
顺便说一句,我认为这里的编码效率参数并不重要,在这两种情况下考虑的是同一个程序员.而且,我认为其他替代品如 python,R 在这里不相关.但是对我们使用的特定库的依赖应该很有趣.
By the way, I don't see coding efficiency parameter being significant here, thinking of the same programmer in both cases. And also, I think the other alternatives like python,R are not relevant here. But dependence on the specific libraries we use should be interesting.
[我是通信系统编码理论的博士生.我一直在使用 matlab/C++ 进行模拟,并且在两种情况下都编写了几万行代码的合理经验]
推荐答案
我已经使用 Matlab 和 C++ 大约 10 年了.对于为我的研究实施的每个数值算法,我总是从使用 Matlab 进行原型设计开始,然后将项目转换为 C++ 以获得 10 到 100 倍(我不是在开玩笑)的性能改进.当然,我将优化的 C++ 代码与完全矢量化的 Matlab 代码进行比较.平均而言,改进幅度约为 50 倍.
I have been using Matlab and C++ for about 10 years. For every numerical algorithms implemented for my research, I always start from prototyping with Matlab and then translate the project to C++ to gain a 10x to 100x (I am not kidding) performance improvement. Of course, I am comparing optimized C++ code to the fully vectorized Matlab code. On average, the improvement is about 50x.
这两种编程语言背后都有很多微妙之处,以下是一些误解:
There are lot of subtleties behind both of the two programming languages, and the following are some misunderstandings:
Matlab 是一种脚本语言,但 C++ 是编译的
Matlab 使用 JIT 编译器将您的脚本翻译成机器码,使用 Matlab 提供的编译器,您最多可以将速度提高 1.5 到 2 倍.
Matlab uses JIT compiler to translate your script to machine code, you can improve your speed at most by a factor 1.5 to 2 by using the compiler that Matlab provides.
Matlab 代码可能能够完全矢量化,但您必须在 C++ 中手动优化代码
完全矢量化的 Matlab 代码可以调用用 C++/C/Assembly 编写的库(例如 Intel MKL).但是普通的 C++ 代码可以被现代编译器合理地向量化.
Fully vectorized Matlab code can call libraries written in C++/C/Assembly (for example Intel MKL). But plain C++ code can be reasonably vectorized by modern compilers.
Matlab 提供的工具箱和例程应该经过很好的调整并且应该具有合理的性能
没有.除线性代数例程外,性能普遍较差.
No. Other than linear algebra routines, the performance is generally bad.
与矢量化的 Matlab 代码相比,您在 C++ 中可以获得 10 倍~100 倍的性能的原因:
The reasons why you can gain 10x~100x performance in C++ comparing to vectorized Matlab code:
在 Matlab 中调用外部库 (MKL) 需要花费时间.
Calling external libraries (MKL) in Matlab costs time.
Matlab 中的内存是动态分配和释放的.例如小矩阵乘法:A = B*C + D*E + F*G
需要 Matlab 创建 2 个临时矩阵.而在 C++ 中,如果您事先分配内存,则创建 NONE.现在想象你将该语句循环了 1000 次.C++ 中的另一个解决方案是由 C++11 Rvalue 参考提供的.这是C++最大的改进之一,现在C++代码可以和普通C代码一样快了.
Memory in Matlab is dynamically allocated and freed. For example, small matrices multiplication:A = B*C + D*E + F*G
requires Matlab to create 2 temporary matrices. And in C++, if you allocate your memory before hand, you create NONE. And now imagine you loop that statement for 1000 times. Another solution in C++ is provided by C++11 Rvalue reference. This is the one of the biggest improvement in C++, now C++ code can be as fast as plain C code.
如果要做并行处理,Matlab模型是多进程的,C++方式是多线程的.如果您有许多需要并行化的小任务,C++ 可提供多达多个线程的线性增益,但在 Matlab 中您可能会获得负面的性能增益.
If you want to do parallel processing, Matlab model is multi-process and the C++ way is multi-thread. If you have many small tasks needing to be parallelized, C++ provides linear gain up to many threads but you might have negative performance gain in Matlab.
C++ 中的向量化涉及使用内在函数/汇编,有时 SIMD 向量化只能在 C++ 中实现.
Vectorization in C++ involves using intrinsics/assembly, and sometimes SIMD vectorization is only possible in C++.
在 C++ 中,有经验的程序员可以完全避免 L2 缓存未命中甚至 L1 缓存未命中,从而将 CPU 推到其理论吞吐量极限.仅由于这个原因,Matlab 的性能可能会落后 C++ 10 倍.
In C++, it is possible for an experienced programmer to completely avoid L2 cache miss and even L1 cache miss, hence pushing CPU to its theoretical throughput limit. Performance of Matlab can lag behind C++ by a factor of 10x due to this reason alone.
在 C++ 中,计算密集型指令有时可以根据它们的延迟(在汇编或内部函数中仔细编码)和依赖性(大部分时间由编译器或 CPU 硬件自动完成)进行分组,这样理论上的 IPC(指令每个时钟周期)可以达到并填充 CPU 管道.
In C++, computational intensive instructions sometimes can be grouped according to their latencies (code carefully in assembly or intrinsics) and dependencies (most of time is done automatically by compiler or CPU hardware), such that theoretical IPC (instructions per clock cycle) could be reached and CPU pipelines are filled.
然而,与 Matlab 相比,C++ 的开发时间也是 10 倍!
However, development time in C++ is also a factor of 10x comparing to Matlab!
你应该使用 Matlab 而不是 C++ 的原因:
The reasons why you should use Matlab instead of C++:
数据可视化.我认为没有 C++ 我的职业生涯可以继续,但没有 Matlab 我将无法生存,因为它可以生成漂亮的绘图!
Data visualization. I think my career can go on without C++ but I won't be able to survive without Matlab just because it can generate beautiful plots!
低效率但数学上强大的内置例程和工具箱.先得到正确答案再谈效率.人们可以在 C++ 中犯一些细微的错误(例如将 double 隐式转换为 int)并得到某种正确的结果.
Low efficiency but mathematically robust build-in routines and toolboxes. Get the correct answer first and then talk about efficiency. People can make subtle mistakes in C++ (for example implicitly convert double to int) and get sort of correct results.
表达您的想法并向您的同事展示您的代码.Matlab代码比C++更容易阅读,也更短,而且Matlab代码无需编译器也能正确执行.我只是拒绝阅读其他人的 C++ 代码.我什至不使用 C++ GNU 科学库,因为无法保证代码质量.对于研究人员/工程师来说,将 C++ 库用作黑匣子并将准确性视为理所当然是危险的.即使对于商业 C/C++ 库,我记得英特尔编译器去年在其 sin() 函数中出现了sign 错误,并且 MKL 中也出现了数值精度问题.
Express your ideas and present your code to your colleagues. Matlab code is much easier to read and much shorter than C++, and Matlab code can be correctly executed without compiler. I just refuse to read other people's C++ code. I don't even use C++ GNU scientific libraries because the code quality is not guaranteed. It is dangerous for a researcher/engineer to use a C++ library as a black box and take the accuracy as granted. Even for commercial C/C++ libraries, I remember Intel compiler had a sign error in its sin() function last year and numerical accuracy problems also occurred in MKL.
使用交互式控制台和工作区调试 Matlab 脚本比 C++ 调试器高效得多.在 Matlab 中查找索引计算错误可以在几分钟内完成,但在 C++ 中,如果为了速度而删除边界检查,则可能需要数小时才能弄清楚为什么程序会随机崩溃.
Debugging Matlab script with interactive console and workspace is a lot more efficient than C++ debugger. Finding an index calculation bug in Matlab could be done within minutes, but it could take hours in C++ figuring out why the program crashes randomly if boundary check is removed for the sake of speed.
最后但并非最不重要的:
因为一旦 Matlab 代码被向量化,程序员就没有太多可以优化的余地,所以与 C++ 代码相比,Matlab 代码性能对代码质量的敏感度要低得多.因此最好在 Matlab 中优化计算算法,稍微好一点的算法通常在 Matlab 中的性能稍微好一点.另一方面,C++中的算法测试需要优秀的程序员以相同的方式编写或多或少优化的算法,并确保编译器不会以不同的方式优化算法.
Because once Matlab code is vectorized, there is not much left for a programmer to optimize, Matlab code performance is much less sensitive to the quality of the code comparing with C++ code. Therefore it is best to optimize computation algorithms in Matlab, and marginally better algorithms normally have marginally better performance in Matlab. On the other hand, algorithm test in C++ requires decent programmer to write algorithms optimized more or less in the same way, and to make sure the compiler does not optimize the algorithms differently.
我最近在 C++ 和 Matlab 方面的经验:
去年做了几个大型的Matlab数据分析工具,苦于Matlab速度慢.但是我能够通过以下技术将我的 Matlab 程序速度提高 10 倍:
I made several large Matlab data analysis tools in the past year and suffered from the slow speed of Matlab. But I was able to improve my Matlab program speed by 10x through the following techniques:
运行/分析 Matlab 脚本,在 C/C++ 中重新实现关键例程并使用 MEX 进行编译.关键例程很可能在逻辑上很简单,但在数字上很重.这将速度提高了 5 倍.
Run/profile the Matlab script, re-implement critical routines in C/C++ and compile with MEX. Critical routines are mostly likely logically simple but numerically heavy. This improves speed by 5x.
简化.m"通过注释所有不必要的安全检查和输出参数计算,来删除随 Matlab 工具箱一起提供的文件.请注意,修改后的代码不能与其他用户脚本一起分发.这将速度再提高了 2 倍(在 C/C++ 和 MEX 之后).
Simplify ".m" files shipped with Matlab tool boxes by commenting all unnecessary safety checks and output parameter computations. Please be reminded that the modified code cannot be distributed with the rest of the user scripts. This improves speed by another 2x (after C/C++ and MEX).
改进后的代码在 Matlab 中约为 98%,在 C++ 中约为 2%.
The improved code is ~98% in Matlab and ~2% in C++.
我相信如果整个工具用 C++ 编码,速度可以再提高 2 倍(总共 20 倍),这是计算例程的约 100 倍速度提高.然后硬盘驱动器 I/O 将支配程序运行时间.
I believe it is possible to improve the speed by another 2x (total 20x) if the entire tool is coded in C++, this is ~100x speed improvement of the computation routines. The hard drive I/O will then dominate the program run time.
Mathworks 工程师的问题:
当 Matlab 代码完全矢量化时,性能限制因素之一是矩阵索引操作.例如,需要对维度为 5000x5000 的矩阵 A 进行有限差分运算:
When Matlab code is fully vectorized, one of the performance limiting factor is the matrix indexing operation. For instance, a finite difference operation needs to be performed on Matrix A which has a dimension of 5000x5000:
B = A(:,2:end)-A(:,1:end-1)
矩阵索引操作使 Matlab 代码比 C++ 代码慢了数倍.能否提高矩阵索引性能?
The matrix indexing operation makes the Matlab code multiple times slower than the C++ code. Can the matrix indexing performance be improved?
这篇关于性能权衡 - MATLAB 何时比 C/C++ 更好/更慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!