Board logo

标题: 多核多处理器架构软件设计的注意事项简介 [打印本页]

作者: look_w    时间: 2018-1-9 16:18     标题: 多核多处理器架构软件设计的注意事项简介

简介计算硬件正在快速蓬勃发展。在时钟速度呈平稳状态的同时,晶体管密度在不断增长。处理器制造商希望通过让每个芯片拥有多个核和硬件线程来提高多处理能力。例如, 对称多处理器架构通过每个核支持多达 4 个线程、每个芯片支持 8 个核、每台服务器支持 32 个芯片插槽来实现高度并行性,总共 1024 个并发硬件线程。相比之下, 架构仅支持每个核 2 个线程、每个芯片 2 个核、每台服务器 32 个芯片插槽,总共 128 个并行硬件线程。
开发软件时,目前设计人员需要考虑可能会部署软件的多处理器、多核架构。这是因为:
本文将会简要介绍为多核、多处理器环境设计软件时的一些重要注意事项。
            在芯片多线程、多核、多处理器架构上软件可伸缩性的阻碍应用程序应该能够在多核、多处理器环境中更好地伸缩、更出色地执行。但是,如果应用程序设计的效率低下,则可能会在这样的环境中执行得较差,但通过使用可用的计算资源可以更好地伸缩和更出色地执行。这个可伸缩性的一些重要阻碍可能是:
低处理器利用率可能会明确表明资源利用率未达到最佳值。为了了解性能问题,您需要评估一下应用程序是否具有太少或太多的线程,是否有锁定或同步问题、网络或 I/O 延迟、内存抖动或其他内存管理问题。只要资源是花费在有意义的工作的应用程序线程上,高处理器利用率通常都会不错。
            芯片多线程 (CMT)、多核和多处理器 (MP) 系统概述在讨论芯片多线程、多核、多处理器环境的设计注意事项之前,我们会简要介绍这类系统。图 1 所述的系统有两个处理器,每个处理器有两个核心,并且每个核心有两个硬件线程。每个核心有一个 L1 缓存和一个 L2 缓存。因此,每个核心可能都拥有自己的 L2 缓存,或者同一个处理器上的核心可能会共享 L2 缓存。同一个核上的硬件线程会共享 L1 和 L2 缓存。
图 1. 一个典型的芯片多线程、多核、多处理器系统所有核和处理器都共享系统总线,并通过系统总线访问主要内存或 RAM。对于应用程序和操作系统,该系统看起来就像是 8 个逻辑处理器。
以下重要概念将帮助我们了解为这样一个芯片多线程、多核、多处理器环境设计应用程序时所面临的挑战。
缓存一致性缓存一致性是表示处理器缓存中的数据项目值与系统内存中的数据项目值相同的一种状态。该状态对于软件来说是透明的。但是,系统为了保持缓存一致性而执行的操作可能会影响软件的性能。
考虑这样一个示例:我们假定在图 1 所述的系统中,线程 1 正在处理器 0 上运行,而线程 2 正在处理器 1 上运行。如果这两个线程都正在读取和写入相同的数据项,那么该系统必须执行额外的操作,以确保在进行每个读取和写入操作时,线程都看到相同的数据值。
当线程 1 在与线程 2 共享的数据项中执行写入操作时,会在其处理器缓存和系统内存中更新该数据项,但不会在线程 2 处理器的缓存中立即更新数据,因为线程 2 可能不再需要访问该数据项。如果线程 2 之后访问该数据项,则其处理器上的缓存子系统必须首先从系统内存中获取新的数据值。因此,线程 1 的写入会迫使线程 2 在下次访问该数据时等待从系统内存中读取数据。仅当数据被其中一个线程修改时,才会出现这种情况。如果每个线程都进行了一系列的写入操作,那么这可能会严重影响系统的性能,因为所有时间都花费在等待更新系统内存中的数据值上。这种情况被称为“乒乓效应”,当在多处理器和多核系统上运行时,应避免发生这种情况,这是一项重要的软件设计注意事项。
嗅探 - Snooping这是一个跟踪每个缓存行的状态的缓存子系统。该系统使用一个称为 “总线动态监视” 或者称为“总线嗅探” 的技术来监视在系统总线上发生的所有事务,以检测缓存中的某个地址上何时发生了读取或写入操作。
当这个缓存子系统在系统总线上检测到对缓存中加载的内存区域进行的读取操作时,它会将该缓存行的状态更改为 “shared”。如果它检测到对该地址的写入操作时,会将缓存行的状态更改为 “invalid”
该缓存子系统想知道,当该系统在监视系统总线时,系统是否在其缓存中包含数据的惟一副本。如果数据由它自己的 CPU 进行了更新,那么这个缓存子系统会将缓存行的状态从 “exclusive” 更改为 “modified”。如果该缓存子系统检测到另一个处理器对该地址的读取,它会阻止访问,更新系统内存中的数据,然后允许该处理的访问继续进行。它还允许将该缓存行的状态标记为 shared
有关这些概念的详细信息,请参阅  部分中有关 “多核多处理器系统的软件设计问题” 的文章。
多核多处理器环境对软件设计决策的影响当设计要在多核或多处理器系统上运行的软件时,主要的考虑事项是如何分配将在可用的处理器上完成的工作。分配该工作的最常用方法是使用一个线程模型,该模型可将工作分成可以在不同处理器上并行运行的各个执行单元。如果线程之间彼此完全独立,那么它们的设计无需考虑它们之间的交互方式。例如,在一个系统上运行的两个程序,每个程序都使用单独的进程在自己的核心上运行,因此无需彼此进行关注。程序的性能不会受到任何影响,除非它们争用共享的资源,比如系统内存或相同的 I/O 设备。
接下来要讨论的重点是核心和处理器与主要内存的沟通方式,以及这对软件设计决策有何影响。
请参见以下重要的设计注意事项。
避免内存争用在内存和缓存中,各种不同的核共享一个通用的数据区域,这需要在它们之间进行同步。当不同的核同时访问同一个数据区域时,会发生内存争用。在不同的核之间同步数据会因总线通信、锁定成本以及缓存缺失而有很大的性能损失。
如果应用程序有多个线程,并且所有线程都更新或修改同一个内存地址,那么正如前面部分所讨论的那样,为了保持缓存一致性,可能会产生一次重大的乒乓效应。这会导致性能降低。
有关的详细信息,请参阅  部分中 “多核平台的内存问题” 文章的 “内存争用” 部分。该文章包含一个简单的程序,此程序演示了内存争用的不良影响。该示例展示,即使多个线程之间只共享一个变量,当对更新使用原子指令时,性能损失也会很大。
避免内存争用的技巧




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0