By Mike P. (Intel), Added 2015 年 7 月 8 日算法
现代高性能计算机由下列资源组合构建而成:多核处理器、众核处理器、大型高速缓存,高带宽进程间通讯结构和高速 I/O 功能。 高性能软件需通过设计,以充分利用这些丰富的资源。 不管是从新构建并/或调优现有应用以发挥最高性能,或为现有或将来设备构建新应用,了解编程模型和高效利用资源之间的相互做用极其关键。 以此为起点,全面了解代码现代化。 关于性能,您的代码相当重要!编程
构建软件的并行版本可以使应用在更短的时间内运行指定的数据集,在固定时间内运行多个数据集,或运行非优化软件禁止运行的大型数据集。 并行化的成功一般经过测量并行版本的加速(相对于串行版本)来进行量化。 除了上述比较以外,将并行版本加速与可能加速的上限进行比较也十分有用。 经过阿姆达尔定律和古斯塔夫森定律能够解决这一问题。数组
出色的代码设计将几个不一样层面的并行化均考虑在内。缓存
开发可以高效使用这三层并行化,并具有高性能的代码是实现代码现代化的最佳选择。性能优化
综合考虑这几点会对设备的内存模式产生积极的影响:主内存容量与速度、与内存位置相关的内存访问时间、高速缓存容量与数量,以及内存一致性要求。网络
矢量并行化时,若是出现数据不对齐,会严重影响性能。 数据应以高速缓存友好型方式进行整理。 若是不这样,当应用请求不在高速缓存内的数据时,性能将会降低。 当所需的数据在高速缓存内,内存访问速度会达到最快。 高速缓存之间的数据传输均以高速缓存行进行,所以,若是下一组数据不在当前高速缓存行内,或分散于多个高速缓存行,应用的高速缓存效率会下降。数据结构
除法和超越数学函数很是昂贵,即便指令集直接支持这些函数。 若是您的应用在运行时代码内使用多项除法和平方根运算,由于硬件内的功能单元有限,性能会有所下降;链接这些单元的管道可能会占主导。 因为这些指令很是昂贵,开发人员但愿高速缓存使用频率较高的值,以提高性能。多线程
“一刀切”的技术不存在。 人们太过于依赖正在处理的某个问题和对代码的长期要求,但优秀的开发人员会关注不一样层面的优化,不只知足当前须要,还会知足将来需求。架构
英特尔构建了一套完整的工具来协助代码现代化,包括编译器、资源库、调试器、性能分析器,并行优化工具等等。 此外,做为并行计算机开发领域的领导者,英特尔以其超过三十年的丰富经验为基础提供网络研讨会、文档、培训示例,以及最佳方法和案例研究。app
代码现代化优化框架以系统化方式进行应用性能优化。 该框架将应用分为 5 个优化阶段,各阶段相互做用,相互影响,以共同提高应用性能。 可是,启动优化流程以前,您应考虑应用是否须要从新构建(根据如下指南)以实现最高性能,而后按照代码现代化优化框架进行优化。
借助该优化框架,应用可在英特尔® 架构上实现最高性能。 这种分布式方法有助于开发人员在最短的时间内实现最高的应用性能。 换句话说,它支持程序在执行环境中最大限度地使用全部的并行硬件资源。 这 5 个阶段分别为:
第 1 阶段
在开始优化项目时,您须要选择一个优化开发环境。 该选择对于后续步骤具备重要的影响。 它不只会影响您获得的结果,还能大幅减小您的工做量。正确的优化开发环境能够为您提供出色的编译器工具、现成的优化库、调试工具和性能评测工具,帮助您准确地查看代码在运行时正在作什么。 查看英特尔® Advisor XE工具中的网络研讨会,并以此识别矢量化和线程化机会。
第 2 阶段
用尽了可供使用的优化解决方案后,若是还要发挥应用的更高性能,您须要启动与应用的源代码相关的优化流程。 在开展活动并行编程以前,您须要确保应用在进行向量化和并行化处理以前可提供正确的结果。 一样重要的是,您须要确保应用可以以最少的运算获得正确的结果。 您要考虑数据和算法相关的问题,如:
您还必须处理语言相关的性能问题。 若是您使用的是 C/C++,与该语言相关的问题包括:
exp()
与 expf()
;abs()
与 fabs()
第 3 阶段
尝试矢量级并行化。 首先尝试对内层循环进行矢量化。 为了获取高效的矢量循环,请确保控制流分散达到最少,以及内存访问保持一致。 外层循环矢量化是一种用于加强性能的技术。 默认状况下,编译器会对嵌套循环结构中最内层的循环进行矢量化处理。 但在某些状况下,最内层循环中的迭代数量较小。 此时,对最内层循环进行矢量化有些得不偿失。 可是,若是外层循环中具备更多的工做,则可使用一个基本函数组合(strip-mining 和编译指示/指令 SIMD)在外层循环强制执行矢量化操做,以实现更好的效果。
第 4 阶段
如今咱们要进行线程级并行化处理。 肯定最外层,并尝试对该层进行并行化处理。 显然,这要求维护潜在数据竞跑,并在须要时将数据声明移到循环内部。 它还要求以高效利用高速缓存的方式维护数据,以下降跨多条并行路径进行数据维护所产生的开销。 之因此对最外层进行并行化处理,是但愿为每条独立线程提供尽量多的工做。 阿姆达尔定律代表: 使用多台处理器的程序在并行计算过程所实现的加速受制于程序顺序片断所需的时间。 因为工做量须要用来弥补并行化所产生的开销,所以有利于每条线程拥有尽量多的并行工做。 若是因为不可避免的数据依赖性致使最外层没法实现并行化,请尝试对可以正确实现并行化的下一个最外层进行并行化处理。
第 5 阶段
最后咱们要作的是多节点(队列)并行化。 许多开发人员认为,消息传递接口 (MPI) 就是“仅运行”于场景背后的黑匣子,将数据从一项 MPI 任务传输到另外一项。 对于开发人员来讲,MPI 的魅力在于其算法编码独立于硬件。 而开发人员担心的是,因为众核架构采用 60 多个内核,任务之间的通讯可能会在单个节点内部或跨节点产生通讯风暴。 为了缓解这些通讯瓶颈,应用可采用混合技术,混合使用几项 MPI 任务和几条 OpenMP 线程。
通过良好优化的应用可处理矢量并行化、多线程并行化和多节点(队列)并行化。 然而,为了高效完成这些并行化,可以使用标准分布式方法,以确保兼顾到各阶段的层面。 根据个独立应用的特定需求,能够(一般)对上述阶段进行从新排序;您能够在某一阶段迭代两次以上,以实现预期性能。
根据咱们的经验,必须实施全部阶段,以确保应用不只可以在目前的可扩展硬件上实现出色性能,还可在将来硬件上进行有效扩展。
试试看!