找回密码
 立即注册
首页 业界区 安全 HPX高性能并行编程1:C++标准和标准库

HPX高性能并行编程1:C++标准和标准库

怃膝镁 2025-8-8 14:09:57
1 C++、C++ 标准和 C++ 标准库

1.1 C++、C++ 标准和并行编程简史

1.png

C++ 基于 Dennis Ritchie 在贝尔实验室工作期间于 1969 年至 1973 年创建的编程语言 C。1973 年,Ritchie 的编译器被用于编译 PDP-11 计算机的 Unix 内核。这是第一次用汇编语言以外的语言编写操作系统。
遗憾的是,直到 1989 年,官方的 C 标准才出台,各种编译器实现都导致了未指定的行为。然而,当时有一个非官方的规范,即 K&R C,它基于 Kernighan 和 Ritchie 于 1978 年撰写的书籍。多年来,C 编程语言中添加了许多语言特性。并非所有编译器都支持所有这些特性。因此,人们一致认为需要一个官方的 C 标准。
美国国家标准协会 (ANSI) 于 1983 年成立了一个委员会。该协会于 1989 年通过了 ANSI X3.159-1989《编程语言 C》标准。这是 C 编程语言的第一个官方标准,称为 C 89。然而,该标准是由 ANSI 发布的,并非国际标准。因此,国际标准化组织 (ISO) 于 1990 年修订了 C 89 标准,并将其发布为 ISO/IEC 9899:1990。由此,第一个国际标准 C 90 应运而生。需要注意的是,C 89 和 C 90 是同一个标准,只是名称不同。后来,C 99 (ISO/IEC 9899:1999) 标准发布。2011 年、2018 年和 2023 年,C 11、C 18 和 C 23 标准相继发布。
从 1990 年起,C 语言实现了标准化,因此所有希望符合标准的编译器都必须遵循 C 标准。这极大地简化了为不同机器和架构编写代码的过程。可以说,认识到标准在编程中的价值是当时最伟大的技术进步。
与此同时,1978年,在AT&T工作的Bjarne Stroustrup开始开发“带类的C语言”。Stroustrup希望以Simula67的风格编写高效的系统程序。因此,他为C语言添加了更好的类型检查、数据抽象和面向对象编程。第一个版本于1983年在内部使用,后来更名为C++。1985年,第一个商业实现发布。然而,当时还没有官方标准,但Stroustrup出版了一本书,就像Kernighan和Ritchie那样。
正如我们在标准化过程中发现的那样,程序员能够分离关注点,软件的运行效果就越好。标准帮助用户将对编译器实现和机器架构的担忧与代码逻辑区分开来。类似地,许多C++语言特性和库代表了进一步的关注点分离努力,使程序员能够一次专注于更少的问题。
类允许将字符串、iostream 或复数等类型的基本逻辑与使用它们的代码和实现它们的代码分开。虽然可以使用 C 语言进行面向对象编程(主要是因为它支持结构体),但 C++ 通过运算符重载、构造函数和析构函数、私有数据和一致性检查为面向对象范式提供了额外的支持。
在模板出现之前,程序员如果想要使用向量或映射之类的类型,必须为每种类型重新实现类似的逻辑多次。这种重新实现带来了维护方面的挑战,因为每当需要修改代码时,都必须更新每一段重复的逻辑。模板和泛型编程改变了这种情况。同样,用 C 语言编写泛型程序也是可行的。在 C++ 的早期,诸如映射之类的类是通过大量使用 C 预处理器来实现的。然而,通过模板,C++ 为这种编程风格提供了更好的支持和错误检查。
标准以及类和泛型使程序员能够查看程序的各个部分,而无需一次性理解整段代码。通过允许程序员专注于各个部分,编写大型复杂代码的任务变得更容易处理。
然而,并行编程仍然是一个挑战。为什么呢?
作为编程社区对标准价值和力量的认可的一部分,MPI 标准于 1994 年诞生。虽然我们不会在这个独立于语言的并行编程库上花费太多时间,但我们注意到它仍然是分布式并行编程中最广泛认可和实施的跨语言标准。曾有一段短暂的时期,人们尝试将标准 C++ 绑定到 MPI,但这些绑定存在问题,最终在 MPI 3.0 标准中被移除。
遗憾的是,虽然 MPI 使得分布式编程在各种平台和各种语言上都变得可靠,但它并没有让编写并行代码变得特别容易。
1997 年,OpenMP 标准开始发展。到 2005 年,它确定了一种在 FORTRAN 和 C/C++ 上实现单节点并行性能的标准方法。OpenMP 的一个优点是它在注释或指令中使用声明式并行。这种机制使得将代码逻辑与并行性分离变得更加容易。
使用 OpenMP 和 MPI,可以相当简单地实现批量同步编程风格,其中一组线程以锁步方式工作并交换信息。这样的代码在几乎所有超级计算机上都具有良好的扩展性和高性能。它们还经常使用屏障机制,使所有线程和进程在某个时刻同步。
许多程序员并不满足于这些机制所能实现的效果。C++ 11 引入了线程、互斥量、原子操作、Future 和异步方法调用,为我们提供了在单节点内进行并行编程的标准。它还引入了智能指针,帮助清理多个线程持有的数据。
C++ 17 和 C++ 20 都为程序员提供了重要的附加功能,包括并行算法。
然而,充分利用任何机器至今仍然是一个挑战。本书将探讨目前可能实现的目标,并酌情提供编程方法和风格的指导。
我们指出,程序员应尽可能将代码的并行逻辑与试图执行的计算清晰地隔离开来。模块化和关注点分离的原则仍然是创建成功的大型程序的关键。
此外,C++ 教学的标准化也在不断推进。 SG20 的《Guidelines for Teaching C++ to beginners》(ISO P1389)是针对入门级 C++ 教学指南的一次尝试。在第一阶段,即基础知识部分,本书涵盖了以下基础知识:容器、范围、lambda 函数和迭代器用法。在第二阶段,该提案推荐了以下 C++ 特性:智能指针和并行算法。在第三阶段,该提案推荐了以下 C++ 特性:泛型编程和无需模板元编程的模板。本书更进一步,重点关注并行和分布式编程。下图总结了 C++ 标准的历史,并重点介绍了本书中使用的特性。
2.png

参考资料


  • 软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
  • 本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
  • python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
  • Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
  • python八字排盘 https://github.com/china-testing/bazi
  • 联系方式:钉ding或V信: pythontesting
1.2 标准模板库 (STL:Standard Template Library) 和 C++ 标准库

Dave Musser 于 1971 年使用泛型编程完成了泛型库的初稿。Dave Musser 和 Alexander Stepanov 在中创造了“泛型编程”一词。Alexander Stepanov 继续研究 Musser 的泛型库思想,并于 1987 年开发了第一个使用 Ada 编程语言的库。Stepanov 和 Lee 在惠普 (HP) 工作期间将他们的库命名为标准模板库 (STL)。后来,STL 以开源形式发布。STL 是第一个用于 C++ 数据结构和算法的泛型库。STL 的设计围绕四个理念:泛型编程、抽象性、值语义和冯·诺依曼计算模型。如今,STL 已不再维护。然而,Stepanov 和 Lee 于 1993 年联系了 C++ 标准化委员会,并提交了他们的库,希望将其纳入 C++ 标准。经过反复讨论,该提案于 1994 年 7 月在 ANSI/ISO 委员会会议上获得批准。这三位研究人员为 C++ 标准中定义的 C++ 标准库的规范奠定了基础。此外,Stepanov 和 McJones 还基于坚实的数学基础撰写了《Elements of programming》一书,供实际编程使用。
请注意,标准模板库和 C++ 标准库是两个不同的东西。C++ 标准库是由 C++ 标准指定的。C++ 标准指定的 C++ 标准库有许多可用的实现。下表 2.1 列出了最常见的活跃实现。C++ 标准库有一个由 Cray® 开发的商业实现,即 Cray® C++ 标准库。所有其他实现均可作为开源软件获取。 Microsoft® 发布了用于 MSVC 工具集和 Visual Studio IDE 的 Microsoft® C++ 标准库。这是 Windows 操作系统最常用的实现。第二个 C++ 标准库由是 NVIDIA® C++ 标准库。该库的特殊之处在于其算法和数据结构可以在 CPU 和 NVIDIA® GPU 上使用。所有其他库都只能在 CPU 上运行。Linux 操作系统上最常见的 C++ 标准库是 GNU C++ 标准库。另一个 C++ 标准库是 LLVM C++ 标准库。C++ 标准库的最新实现是 HPX,即 C++ 并行和并发标准库。本书将使用 GNU C++ 标准库和 Microsoft C++ 标准库作为示例。对于分布式示例,我们将使用 C++ 并行和并发标准库 (HPX)。有关更多详细信息以及每个 C++ 标准库中可用的库特性,请参阅表 2.1。表 3 列出了 C++ 标准库的各种实现。除一个库外,所有库均采用开源许可证。
3.png

1.3 C++ 编译器

以下是可用的 C++ 编译器。请注意,可用的编译器还有很多,但我们只讨论那些最知名且在超级计算机上最常用的编译器。首先,我们考虑各公司提供的编译器。在 Cray® 超级计算机上,尤其是在使用消息传递接口 (MPI) 进行分布式计算时,会使用 HPE® Cray® 编译器。英特尔® 的 icc 编译器针对英特尔® CPU 进行了特殊优化。同样,IBM® XL 编译器针对 IBM® Power™ 架构进行了特殊优化,AMD® 的 AOCC 编译器针对 AMD® CPU 进行了特殊优化,富士通® 的 fcc 编译器针对 A64FX™ 架构进行了特殊优化,Arm® 的 armclang++ 编译器针对 Arm® 架构进行了特殊优化。微软® 为 Windows 操作系统提供了 Visual C++。最后,NVIDIA® 提供了 pgc++ 编译器,它是 NVIDIA® HPC SDK 的一部分。
以下是可用的社区驱动编译器。首先是 GNU 项目的 g++。该编译器在 Linux 上被广泛用作默认的 C++ 编译器。另一个编译器是 LLVM 项目的 clang++。
4.png

本书中的示例已使用 Visual C++、clang++ 和 g++ 编译器测试。有关推荐编译器和版本的更多详细信息,请参阅附录 C。但是,由于 C++ 已实现 ISO 标准化,所有支持 C++ 17 或 C++ 20 的编译器都应该能够正常工作。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册