如何使用 C/C++ 在 DSP 上工作?

信息处理 matlab 数字通信 C C++ 硬件
2021-12-23 11:01:17

我一直在使用 MATLAB 进行信号处理。许多来自DSP的通信背景公司都问我是否非常了解C/C++。我对为什么这些公司使用 C/C++ 进行信号处理感到困惑。为什么不使用 MATLAB,因为它拥有所有可用的库/工具箱并且易于使用?我只是想知道 C/C++ 如何适合使用信号处理的无线通信项目。该项目的流程是什么?

使用 C/C++ 的一般目的是什么?如何将 C/C++ 用于 DSP?有哪些参考资料?我需要开始使用 C/C++ 来构建 DSP 算法。我不知道如何将 C/C++ 用于 DSP 应用程序。

4个回答

MATLAB 是一个桌面计算环境,旨在使批量数学变得容易。如果您能够访问 MATLAB 源代码,您会发现,当您深入研究它时,实际的计算位是用 C++、C 或(很可能)Fortran编写的。

然而,它与底层数学包的接口又大又慢,而且不是可以轻松实时运行的东西*

与信号处理相关的开发工作的一般过程或多或少如下:

首先,有人进行基础研究,看看所提议的是否可行。这将涉及混合基础数学和实验数学。基本的数学部分是 - 数学。输出是一系列研究论文或白皮书。实验数学部分很可能包括 MATLAB,但可能涉及再次使用 Python 和数值包(在我看来,MATLAB 最适合总行数不超过 500 行的程序;除此之外,该语言的笨拙程度超过了 Python 及其可用的软件包对数学的集成不太彻底)。

然后,有人使用上述步骤的输出进行初始系统设计(有时这两个步骤可能同时发生;有时,在简单的SDR的情况下,基础研究已经建立了几十年)。如果您对自己的设计方法进行系统化,您也可以在这里使用 MATLAB 或 Python,但您也会知道处理器(使用 C/C++ 编写的代码)和/或任何数字处理器上可以进行哪些处理逻辑(FPGA或ASIC)。

这个初始系统设计的输出是一个完整详细的算法描述,一直到 C/C++ 中可用的已建立函数(因此,如果没有可用的数学包,则为算术,如果有,则为包的操作)。该初始设计将包括处理器负载的估计,并将分析需要使用哪些处理器,以及如果使用数字逻辑,如何在处理器和数字逻辑之间分配工作。

(请注意,这里的另一种方法是为您提供可以使用的硬件的处方,您的工作是确定可以将多少功能挤入其中。它使用相同的知识库,但通常涉及很多技术工作,以及与非技术利益相关者的大量会议以解释事情并协商每个人都可以接受的解决方案)。

最后得到或设计端点硬件,实现实际设计。这部分在处理器中用 C 或 C++ 完成,在数字逻辑位中用VHDLVerilog完成(可能为了好玩而将一些SystemC放入其中)。这最后一步是最费力的。它不仅需要了解信号处理数学,还需要深入了解数值方法(因为您通常不能只在 64 位浮点中做所有事情:您通常会将您的设计压缩成更小的浮点字,或者入固定基数算术)和一般嵌入式编程的良好做法。

在工作世界中,您要么从最底层开始,实施设计,然后(也许)在工作中学到足够多的知识,可以信任您进行详细的系统设计,然后进入该步骤。或者,你获得了一个具有绝对炸药论文的博士学位,该论文基本上针对有钱人想要解决的某个问题进行了第一个基础研究部分,然后你在余下的职业生涯中进行研究,因为这是知道如何解决问题的唯一方法做初步的系统设计就是要知道如何做详细的设计。

如果您是一名使用 MATLAB 的顶级 DSP 从业者,并且您想实际编写代码,那么您需要确保具备以下技能:

  • 了解所有这些 MATLAB 库调用的实际作用我已经看到很多人认为 DSP 开始和结束于知道要调用哪些 MATLAB 函数的帖子——事实并非如此。如果您只知道要调用哪些 MATLAB 函数,那么首先要弄清楚它们算术上和信号上的作用。
  • 了解如何在 C/C++ 中实现数学。首先学习如何做到这一点,使其完全有效,然后学习如何在减少数据宽度和固定点的情况下做到这一点。然后学习如何做到这一点,以便它运行得很快。如果您没有数值方法文本,请至少获取一个;如果您还在上学,请参加数值方法课程。
  • 学习如何进行嵌入式编程,或者至少开始学习它。这意味着学习如何编写代码以使其不依赖于任何更高级别的操作系统函数,并学习如何注意使用的内存量,以及至少了解处理器上线程间通信的基础知识没有MMU

* 如果您不知道“实时”在嵌入式系统编程环境中的含义——请学习。

C/C++ 是实时和嵌入式信号处理的标准语言。在大多数情况下,MATLAB 太耗内存而且太慢了。

例如,您的手机或小型蓝牙扬声器中会发生大量信号处理。这些没有足够的资源来运行 MATLAB,而且在任何情况下,它都太低效且太昂贵了。

MATLAB 非常适合研究和开发,但不适合在实际产品中实现或部署。

我来自游戏开发界,在我做我的第一个信号处理程序(在游戏音频过滤器的上下文中)之前我就知道 C/C++ 编程方式,所以我希望我能给你另一个观点。

其他答案提到了速度和内存,虽然这可能是真的,但我想说这不是选择诸如 Matlab 之类的注册或诸如 C 或 C++ 之类的编程语言的最重要原因。

我会说这取决于你想要做什么。如果您尝试进行独立的信号处理,也就是说,您有一些数据,您必须对其进行处理,然后对结果进行一些处理,那么 MATLAB 可能是一个非常好的工具,因为它易于使用,并广为人知并用于此目的。

但是,如果您的信号处理算法被集成到一个大型系统中,您从系统中获取数据,然后对其进行处理,然后将其发送到另一个系统进行进一步处理,那么 MATLAB 可能会产生比它解决的问题更多的问题。

内存和速度绝对是一个因素,但许可是另一个因素。仅仅因为您系统的一小部分使用它,就要求每个使用您的软件的客户购买和安装 MATLAB 是不合理的。

我想说的是,MATLAB 是集成到系统中的糟糕选择。另一方面,C(甚至超过 C++)的最大优点之一是它很容易集成到其他系统中,不仅是用 C 编写的系统,还包括JavaC#PHPRustRubyJavaScript , Python等。您甚至可以将 C 库加载到 MATLAB 本身!

你想写一个VST插件吗?你是用 C 语言做的。你想在 iPhone 中编写一个用于信号处理的Core Audio模块?您可以在 C (或Objective-C)中执行此操作。嵌入式编程?C 或组装。游戏的音频处理?C. 名单还在继续。

C 是系统集成世界的通用语言,所以如果你想编写一段代码可以与尽可能多的系统一起工作,你可能需要认真考虑 C。

不过,您的 MATLAB 经验非常有用。如果您正在设计一种新算法,您可能会发现在使用 C 语言构建最终版本之前,在 MATLAB 中对其进行原型设计和测试会更容易。

我发现甚至将 MATLAB 称为编程语言都具有误导性。——嗯,它图灵完备语言……但Brainfuck (BF) 也是如此。理论上,您可以在其中编写任何软件(只要有足够的内存)——是的。但是你愿意吗?不。

好吧好吧,BF比较被夸大了。人们确实在 MATLAB 中编写了全面的程序,并且他们可以工作,但是我在 MATLAB 中看到的任何更大的项目都是一堆无法维护的黑客攻击。部分原因在于作者往往是工程师、物理学家等,他们在自己的领域很聪明,但从未了解过好的软件工程实践。但事实上,像 MATLAB,尤其是MATLAB 这样的脚本语言会积极鼓励不良做法。

Henning Thielemann 写了一篇非常自以为是的帖子(用德语)。本质是这样的:

einfache Aufgaben noch einfacher und schwierige noch schwieriger zu machen

翻译:脚本语言使简单的任务更容易,而艰巨的任务更难。

特别是在 MATLAB 中,开箱即用的各种强大的标准数值方法的现成可用性使其对初学者非常有吸引力。这本身并没有什么问题——只要你永远不会偏离其他人已经实施的太远。但是,这说明 MATLAB 本身实际上并没有多少是在 MATLAB 中实现的——当然没有高性能的低级代码。

在教育中使用 MATLAB 有充分的理由。学生是否需要花时间学习如何构建项目、如何导入库、如何自己实现低级代码,甚至才能运行一些简单的ODE求解器或 DSP 滤波器?也许不吧。(我个人认为的!)
但是,如果您要为一家公司工作,那么您最终很可能需要这些技能。即使您的工作实际上主要是在 MATLAB 中对 DSP 方法进行原型设计也是如此。即使这涵盖了你 90% 的职责——最终你的代码将需要集成到主项目中,可能会被翻译成另一种语言。如果你不能做到这一点,那么你所有的 MATLAB 代码对公司来说都不会很有价值——他们另一个开发人员做这项工作。(谁将首先需要读入您的 MATLAB,这可能需要相当长的时间。)与此相比,公司聘请已经会 C++ 的人更有意义,即使是主要从事 MATLAB DSP 的工作. 因为即使她在原型制作上花一点时间,她在大规模集成上的效率也会高得多。

即使你的工作打算 100% 使用 MATLAB知道如何用 C 编程也将是一笔巨大的财富,因为这意味着你可以掌握处理器中实际发生的事情,而不管使用什么语言在顶层。


我还驳斥了人们需要在MATLAB 等简单语言C/C++ 等困难语言之间进行选择的普遍假设。这是 Fortran 成为行业标准的时代的遗物(嗯,它仍然存在于某些HPC领域)。如今,有许多替代方案介于这些极端之间,并且在某些情况下可以说更适合快速原型设计和产品代码

  • Julia将此作为其明确的目标。它受到 MATLAB 的强烈启发(IMO过于强烈,以至于继承了它的大部分问题),但同时努力编写可用于任何应用程序的新的、高性能的代码。
  • 现代 C++ 绝不需要看起来像低级 C-ish 代码。它支持强大的面向对象、泛型、函数式等样式,并且有大量成熟的库可供使用。C++ 肯定有一点学习曲线,但最终你可以用它做任何事情,你的代码可以在任何地方运行,包括嵌入式设备。
  • 不可否认, Python是一种脚本语言,但(至少最初)与 MATLAB 的重点非常不同;它根本不适合数字/ DSP应用程序。但是对于干净、可维护的开发,没有太多的困难或样板。然而,到目前为止,它已成为机器学习社区的事实标准,并且拥有非常强大且易于使用的库。SciPy + MatPlotLib几乎与 MATLAB 最强大的方面一样方便,但在更简洁的基础语言和许可许可中。
    Python 仍然存在动态问题,这意味着您不能直接编写高性能的低级代码或在嵌入式应用程序中使用它,但是有许多不错的解决方法,并且这种情况越来越不成问题。
  • Rust采用与 C++ 大致相同的起点(零开销替代 C 并具有更多功能),但试图避免成为如此复杂的庞然大物。
  • 我个人最喜欢的(带着一点盐)是Haskell又是完全不同的背景。Haskell 与上述所有语言都有很大不同。从某种意义上说,它甚至比 Matlab 更高级别,完全是声明式的,但是它这样做的方式使得 Haskell 代码对于大规模开发来说非常健壮。它编译为高性能的本机代码。它也有一个相当大的生态系统,但不幸的是,它远没有 Python 那样维护良好的库。很少有人在数值应用中关注 Haskell。
    OCaml是一个类似的故事,也是一种静态函数式语言,不像 Haskell 那样极端。

该列表可以做得更长,但这超出了这个问题的范围。

学习这些语言中的任何一种都会增加你在就业市场上的价值。
Julia 或 Python 最容易上手。
正如您所注意到的,C 和/或 C++ 将提供最强的直接就业奖金。Rust 可能更容易进入那个世界。
Haskell 或OCaml不会直接让你找到任何 DSP 或机器学习工作,但它们会极大地拓宽你对“编程”的视野,并教你函数式编程风格,这在 C++、JavaScript 或Python 作业。



tl;dr: MATLAB 更像电子表格软件,而不是生产编程语言。