c++ - 性能权衡 - MATLAB 何时比 C/C++ 更好/更慢

标签 c++ c performance matlab

我知道 C/C++ 是一种低级语言,当我们与任何其他高级语言进行比较时,它会生成相对优化的机器代码。但我想还有远不止这些,这从实践中也很明显。

当我做简单的计算,比如对高斯样本集合进行蒙特卡洛平均等时,我发现 C++ 实现或 MATLAB 实现之间没有太大区别,有时实际上 MATLAB 在时间上的表现要好一些。

当我使用数千行代码进行更大规模的模拟时,慢慢地真实的画面出现了。 C++ 仿真显示出卓越的性能,在时间复杂度上比等效的 MATLAB 实现高 100 倍。

大多数情况下,C++ 中的代码几乎是串行的,并且没有明确进行高保真优化。然而,据我所知,MATLAB 本质上做了很多优化。例如,当我尝试生成大量随机样本时,就会出现这种情况,而在 C++ 中使用某些库(如 IT++/GSL/Boost)的等效项的执行速度相对较慢(使用的算法相同,即 mt19937)。

我的问题只是想知道 MATLAB/C++ 在性能方面是否有更简单的权衡。是不是就像人们所说的“无论何时,C/C++ 都是更好的”(经常经历的)?。换个角度看,“除了舒适,MATLAB 还有什么好处?”

顺便说一句,我认为编码效率参数在这里并不重要,在这两种情况下都考虑同一个程序员。而且,我认为其他替代品,如 python,R 在这里不相关。但是对我们使用的特定库的依赖应该很有趣。

[我是通信系统编码理论的博士生。我一直使用 matlab/C++ 进行模拟,并且在这两种情况下都具有编写几万行代码的合理经验]

最佳答案

我已经使用 Matlab 和 C++ 大约 10 年了。对于为我的研究实现的每个数值算法,我总是从使用 Matlab 进行原型(prototype)设计开始,然后将项目转换为 C++ 以获得 10 到 100 倍(我不是在开玩笑)的性能改进。当然,我将优化的 C++ 代码与完全矢量化的 Matlab 代码进行比较。平均而言,改进约为 50 倍。
这两种编程语言背后都有很多微妙之处,以下是一些误解:

  • Matlab 是一种脚本语言,但 C++ 是编译的
    Matlab 使用 JIT 编译器将您的脚本转换为机器代码,使用 Matlab 提供的编译器,您最多可以将速度提高 1.5 到 2 倍。
  • Matlab 代码可能能够完全矢量化,但您必须在 C++ 中手动优化代码
    完全矢量化的 Matlab 代码可以调用用 C++/C/Assembly 编写的库(例如 Intel MKL)。但是普通的 C++ 代码可以被现代编译器合理地向量化。
  • Matlab 提供的工具箱和例程应该很好地调整并且应该具有合理的性能
    不。除了线性代数例程外,性能通常很差。

  • 与矢量化的 Matlab 代码相比,在 C++ 中可以获得 10 倍~100 倍的性能的原因:
  • 在 Matlab 中调用外部库 (MKL) 需要花费时间。
  • Matlab 中的内存是动态分配和释放的。例如,小矩阵乘法:A = B*C + D*E + F*G需要 Matlab 创建 2 个临时矩阵。而在 C++ 中,如果你事先分配内存,你就创建了 NONE。现在想象你将该语句循环了 1000 次。 C++ 中的另一个解决方案由 C++11 Rvalue 引用提供。这是 C++ 最大的改进之一,现在 C++ 代码可以和普通 C 代码一样快。
  • 如果要做并行处理,Matlab模型是多进程的,C++方式是多线程的。如果您有许多需要并行化的小任务,C++ 可以为许多线程提供线性增益,但在 Matlab 中您可能会获得负面的性能增益。
  • C++ 中的向量化涉及使用内在函数/汇编,有时 SIMD 向量化只能在 C++ 中实现。
  • 在 C++ 中,有经验的程序员可以完全避免 L2 缓存未命中甚至 L1 缓存未命中,从而将 CPU 推到其理论吞吐量极限。仅由于这个原因,Matlab 的性能可能落后 C++ 10 倍。
  • 在 C++ 中,计算密集型指令有时可以根据它们的延迟(在汇编或内部函数中仔细编码)和依赖性(大部分时间由编译器或 CPU 硬件自动完成)进行分组,这样理论上的 IPC(每个时钟周期的指令)可以到达并填充 CPU 管道。

  • 然而,与 Matlab 相比,C++ 的开发时间也是 10 倍!
    您应该使用 Matlab 而不是 C++ 的原因:
  • 数据可视化。我认为我的职业生涯可以没有 C++ 继续下去,但没有 Matlab 我将无法生存,因为它可以生成漂亮的情节!
  • 低效率但数学上强大的内置例程和工具箱。先得到正确答案再谈效率。人们可以在 C++ 中犯一些细微的错误(例如将 double 隐式转换为 int )并得到某种正确的结果。
  • 表达您的想法并向您的同事展示您的代码。 Matlab 代码比 C++ 更容易阅读,也更短,而且 Matlab 代码无需编译器也能正确执行。我只是拒绝阅读其他人的 C++ 代码。我什至不使用 C++ GNU 科学库,因为无法保证代码质量。对于研究人员/工程师来说,将 C++ 库用作黑匣子并将准确性视为理所当然是危险的。即使对于商业 C/C++ 库,我记得英特尔编译器有一个 签到 中的错误罪()去年MKL也出现了函数和数值精度问题。
  • 使用交互式控制台和工作区调试 Matlab 脚本比 C++ 调试器高效得多。在 Matlab 中查找索引计算错误可以在几分钟内完成,但在 C++ 中可能需要数小时才能弄清楚如果为了速度而删除边界检查,程序会随机崩溃的原因。

  • 最后但是同样重要的:
    因为一旦 Matlab 代码被矢量化,程序员就没有太多可以优化的余地,所以与 C++ 代码相比,Matlab 代码性能对代码质量的敏感度要低得多。因此最好在 Matlab 中优化计算算法,稍微好一点的算法通常在 Matlab 中的性能稍微好一点。另一方面,C++ 中的算法测试需要优秀的程序员以相同的方式编写或多或少优化的算法,并确保编译器不会以不同的方式优化算法。
    我最近在 C++ 和 Matlab 方面的经验:
    去年做了几个大型的Matlab数据分析工具,苦于Matlab速度慢。但是我能够通过以下技术将我的 Matlab 程序速度提高 10 倍:
  • 运行/分析 Matlab 脚本,在 C/C++ 中重新实现关键例程并使用 MEX 进行编译。关键例程很可能在逻辑上很简单,但在数字上很重。这将速度提高了 5 倍。
  • 通过注释所有不必要的安全检查和输出参数计算来简化 Matlab 工具箱附带的“.m”文件。请注意,修改后的代码不能与其他用户脚本一起分发。这将速度再提高了 2 倍(在 C/C++ 和 MEX 之后)。

  • 改进后的代码在 Matlab 中约为 98%,在 C++ 中约为 2%。
    我相信如果整个工具用 C++ 编码,速度可以再提高 2 倍(总共 20 倍),这是计算例程的约 100 倍速度提高。然后硬盘驱动器 I/O 将主导程序运行时间。
    Mathworks 工程师的问题:
    当 Matlab 代码完全矢量化时,性能限制因素之一是矩阵索引操作。例如,需要对维度为 5000x5000 的矩阵 A 进行有限差分运算:
    B = A(:,2:end)-A(:,1:end-1)
    
    矩阵索引操作使 Matlab 代码比 C++ 代码慢很多倍。能否提高矩阵索引性能?

    关于c++ - 性能权衡 - MATLAB 何时比 C/C++ 更好/更慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20513071/

    相关文章:

    c++ - 在 C++ 中使性能关键方法调用多态化的最快方法?

    c++ - 使用带引用的函数作为带指针的函数?

    c++ - 如何在Linux终端应用程序中检测XOFF和XON

    c - 如何从 ssh session 中获取伪终端主文件描述符?

    c - 在可执行二进制文件中嵌入修订号

    c - 使用数组初始值设定项作为静态数组

    c# - Linq to SQL - 什么更好?

    c# - LINQ 中哪种方法更好?

    c++ - SIGTSTP 信号不阻止 child ?

    c++ - 如何使用 std::vector<std::mutex> 之类的东西?