多核处理器改变了游戏规则。我们只需要看看我们的智能手机就能看到它们卓越的处理能力的影响。在多核之前,处理器性能每年翻一番。随着半导体技术的进步,芯片上的晶体管数量从 1990 年的 100 万个增加到今天的 10 亿个以上。随着小型化的极限越来越近,业界转向多核设计以保持性能改进的步伐,因此现在四核处理器已司空见惯。通过并行处理器内核倍增处理能力的能力可实现非凡的性能。
并发不是一个新话题,但它在多核平台中呈现出一个新的维度。软件开发人员已经习惯于从单个处理器内的任务调度和上下文切换的角度来考虑并发性。然而,对于多个处理器内核,真正的并行性开始发挥作用:每个线程中的指令流在每个内核上并行执行。线程之间的通信通常是使用共享内存来实现的,并且对共享资源的访问同步通常是复杂性的最大来源,如果操作不正确,则是导致错误的主要原因。
编写一个正确的并发程序是出了名的困难,而多核架构使它变得更加困难。由于增加了复杂性,多核平台加剧了并发错误的影响,使它们特别有害。这些错误,包括竞争条件、死锁、活锁和资源匮乏,当它们出现时很难发现,甚至更难以诊断。在单处理器上无错误运行的程序可能会出现潜在错误,例如多核系统上的死锁。并发错误可能会出现异常症状,这些症状在触发它们的初始事件很久之后就会出现,并且通常难以重现。因为在测试过程中很难找到这样的错误,多核系统需要一种新的验证方法,专门解决并发错误。到目前为止,降低这些错误风险的最有效方法是采用多方面的方法,包括同行代码审查、测试,最重要的是,高级静态分析结合了复杂的并发模型。
编程语言支持
释放多核系统的全部性能潜力需要先进的编程技术。由于大多数嵌入式开发人员对多核编程比较陌生,因此引入并发错误的风险非常大。今天,C 和 C++ 仍然是嵌入式系统最流行的编程语言。然而,这些语言的根本弱点之一是它们不是为并发而设计的。最新版本 C11 和 C++11 引入了对多线程的标准化支持。添加了三个特性来解决并发问题:定义多线程程序行为的内存模型;可以被并发线程安全访问的原子数据类型;以及几个同步原语,例如锁和条件变量。尽管有这些改进,
与此同时,Java 越来越受到嵌入式开发人员的欢迎,如今有 28% 的人使用它,它现在是嵌入式系统第三流行的语言。与 C 和 C++ 相比,Java 始终在编程语言语法、源编译器和标准库中内置了对多线程的支持。此外,Java 5 添加了 java.util.concurrent 库,该库在 Java 6 和 Java 7 中进行了扩展,为并发和并行编程提供了广泛的支持。
许多嵌入式设计使用 C 或 C++ 和 Java 的组合。例如,Java 在汽车应用程序中非常流行,因为它为触摸屏显示器或娱乐系统的用户界面编程提供了一种简单的方法。此类应用程序可能有许多层,其中包含用 C 编写的安全关键代码,与运行在用户界面上的非安全关键 Java 代码进行通信。
静态分析工具
多核平台并发程序的最大挑战可能是无法保证能找到所有并发错误。实时执行指令的相对顺序是多线程程序中缺陷的主要来源。当多个线程运行时,它们的指令执行的相对顺序取决于同时处于活动状态的其他线程。如果错误是通过编程错误引入的,非确定性交错可能会导致不可预知的结果。随着指令数量的增加,可能的交错数量会大大增加,这种现象称为组合爆炸。即使是最小的线程也有许多可能的交错。现实世界的并发程序具有天文数字的合法交错,所以测试每一个交织是不可行的。同样,不可能使用同行代码审查或演练来探索每条潜在的执行路径。这是高级静态分析工具擅长的地方。
高级静态分析工具使用符号执行引擎来识别程序中的潜在问题,而无需实际运行程序。它们的工作方式与编译器非常相似,将源代码作为输入,然后对其进行解析并将其转换为中间表示 (IR)。编译器会使用 IR 来生成目标代码,而静态分析工具会保留 IR,也称为模型。检查器通过遍历或查询模型,对代码进行分析以查找常见缺陷、违反策略等,寻找指示缺陷的特定属性或模式。复杂的符号执行技术通过控制流图探索路径,控制流图是一种数据结构,表示语句在程序中执行的顺序。算法跟踪程序的抽象状态,并知道如何使用该状态来排除对不可行路径的考虑。模型的深度决定了工具的有效性。该深度基于内置了多少程序行为知识,一次可以考虑多少程序,以及它反映实际程序行为的准确程度。
许多开发人员利用流行的开源工具来查找 Java 中的错误,包括 FindBugs、PMD 和 CheckStyle。其中最广泛使用的 FindBugs 使用静态分析来识别 Java 程序中数百种不同类型的潜在错误。FindBugs 对 Java 字节码(Java 虚拟机执行的指令形式)进行操作。PMD 和 CheckStyle 检查源代码是否符合编码标准并检测不良做法。
这些工具中的每一个都有其优势。一般来说,静态分析工具的一个重要优势是它们可以在开发早期使用,甚至在测试开始之前就可以发现错误。可用于 Java 的大多数静态分析工具都是通用的,可以捕获一系列表面问题。
与这些开源工具相比,有一些商业产品专门用于非常精确地识别 Java、C 或 C++ 中的并发问题。这些工具包含非常深的模型,使他们能够发现其他工具经常遗漏的并发问题。这些高级静态分析工具中的一些最有效的工具是基于对软件并发行为的前沿学术研究。它们通过整个程序过程间分析提供 C 和 C++ 源代码的高级静态分析,通常可以处理多达 1000 万行代码的程序。除了查找竞争条件和死锁之外,Java 的一种商业工具还可以识别由于错误使用 java.util.concurrent 提供的并发集合库而导致的不可预测的结果。在协调对共享的非并发集合的访问时,它会检测到错误的错误处理或不正确的同步。此外,它还可以帮助诊断由错误的 API 使用、冗余同步和不必要地使用共享可变状态引起的性能瓶颈。
由于许多项目将包括 Java 和 C 或 C++,因此团队会发现在集成开发环境 (IDE) 中使用工具更容易、更高效。有一些工具套件可用于嵌入式和托管平台。商业版本为程序分析、程序检查、程序理解和架构可视化提供自动化工作流程和强大工具。使用带有目标高级静态分析工具的 IDE 使开发人员能够发现现有并发代码的基本设计意图,并识别新代码何时偏离该设计。它在首次引入新的并发缺陷时提供预警,并使用尖端技术帮助开发人员识别和理解它们。
有效的多核系统设计
为多核平台开发嵌入式应用程序需要一种新方法。需要先进的编程技术来利用并行处理内核。跨并行处理器的程序线程交错创建了天文数字的潜在执行路径。这使得不可能测试或审查每一个可能的场景。静态分析提供了唯一可行的方法来探索高度并发系统中软件错误的所有可能代码路径。当与其他代码质量实践(例如代码审查和集成测试)结合使用时,高级静态分析工具可以显着降低由于未发现的并发错误而导致的现场故障风险。
审核编辑:郭婷
-
处理器
+关注
关注
68文章
19165浏览量
229130 -
JAVA
+关注
关注
19文章
2958浏览量
104549 -
C++
+关注
关注
22文章
2104浏览量
73496
发布评论请先 登录
相关推荐
评论