返回 登录
4

什么是代码现代化?

现代高性能计算机由下列资源组合构建而成:多核处理器、众核处理器、大型高速缓存,高带宽进程间通信结构和高速 I/O 功能。 高性能软件需经过设计,以充分利用这些丰富的资源。 无论是重新构建并/或调优现有应用以发挥最高性能,或为现有或未来设备构建新应用,了解编程模型和高效利用资源之间的相互作用极其关键。 以此为起点,全面了解代码现代化。 关于性能,您的代码至关重要!

构建软件的并行版本可使应用在更短的时间内运行指定的数据集,在固定时间内运行多个数据集,或运行非优化软件禁止运行的大型数据集。 并行化的成功通常通过测量并行版本的加速(相对于串行版本)来进行量化。 除了上述比较之外,将并行版本加速与可能加速的上限进行比较也十分有用。 通过阿姆达尔定律和古斯塔夫森定律可以解决这一问题。

出色的代码设计将几个不同层面的并行化均考虑在内。
第一层并行化是矢量并行化(代码内),在大型数据块上执行相同的计算指令。 代码的标量部分和并行部分都将受益于高效的矢量计算。
第二层并行化是线程并行化,其主要特点是单个进程的多条合作线程通过共享内存进行通信,共同处理某项指定任务。
第三层并行化是以独立合作进程的方式开发多个代码时,各代码之间通过消息传递系统进行通信。 这种被称为分布式内存队列并行化,之所以如此命名,是因为每个进程指定一个独有的队列号。
开发能够高效使用这三层并行化,并具备高性能的代码是实现代码现代化的最佳选择。

综合考虑这几点会对设备的内存模式产生积极的影响:主内存容量与速度、与内存位置相关的内存访问时间、高速缓存容量与数量,以及内存一致性要求。

矢量并行化时,如果出现数据不对齐,会严重影响性能。 数据应以高速缓存友好型方式进行整理。 如果不这样,当应用请求不在高速缓存内的数据时,性能将会下降。 当所需的数据在高速缓存内,内存访问速度会达到最快。 高速缓存之间的数据传输均以高速缓存行进行,因此,如果下一组数据不在当前高速缓存行内,或分散于多个高速缓存行,应用的高速缓存效率会降低。

除法和超越数学函数非常昂贵,即使指令集直接支持这些函数。 如果您的应用在运行时代码内使用多项除法和平方根运算,因为硬件内的功能单元有限,性能会有所降低;连接这些单元的管道可能会占主导。 由于这些指令非常昂贵,开发人员希望高速缓存使用频率较高的值,以提升性能。

“一刀切”的技术不存在。 人们太过于依赖正在处理的某个问题和对代码的长期要求,但优秀的开发人员会关注不同层面的优化,不仅满足当前需要,还会满足未来需求。

英特尔构建了一套完整的工具来协助代码现代化,包括编译器、资源库、调试器、性能分析器,并行优化工具等等。 此外,作为并行计算机开发领域的领导者,英特尔以其超过三十年的丰富经验为基础提供网络研讨会、文档、培训示例,以及最佳方法和案例研究。

面向多层并行的代码现代化 5 阶段框架

代码现代化优化框架以系统化方式进行应用性能优化。 该框架将应用分为 5 个优化阶段,各阶段相互作用,相互影响,以共同提升应用性能。 但是,启动优化流程之前,您应考虑应用是否需要重新构建(根据以下指南)以实现最高性能,然后按照代码现代化优化框架进行优化。

借助该优化框架,应用可在英特尔® 架构上实现最高性能。 这种分布式方法有助于开发人员在最短的时间内实现最高的应用性能。 换句话说,它支持程序在执行环境中最大限度地使用所有的并行硬件资源。 这 5 个阶段分别为:
利用优化工具和库:使用英特尔® VTune™ Amplifier 分析工作负载,以确定热点,并使用英特尔® Advisor XE识别矢量化和线程化机会。 使用英特尔编译器生成最佳代码,并在适当的情况下运用英特尔® 数学核心函数库、英特尔® TBB 和 OpenMP* 等优化的资源库。
标量串行优化:保持正确的精度,输入常量,并使用合适的函数和精度标记。
矢量化:利用 SIMD 特性以及数据布局优化。采用高速缓存对齐的数据结构,将结构数组转化为数组结构,并最大限度地减少条件逻辑。
线程并行化:分析线程扩展,并将线程与内核关联。 扩展问题通常是由于线程同步或内存利用率低下所造成的。
将应用从多核扩展到众核(分布式内存队列并行化):扩展对高度并行化应用来说极为重要。 在将执行对象从一种偏爱的英特尔架构(英特尔® 至强™ 处理器)换至另一种(英特尔® 至强融核™ 协处理器)的过程中,最大限度地减少变化并最大限度地增强性能。
图片描述

代码现代化 – 5 阶段的实际运用

第 1 阶段
在开始优化项目时,您需要选择一个优化开发环境。 该选择对于后续步骤具有重要的影响。 它不仅会影响您得到的结果,还能大幅减少您的工作量。正确的优化开发环境可以为您提供出色的编译器工具、现成的优化库、调试工具和性能评测工具,帮助您准确地查看代码在运行时正在做什么。 查看英特尔® Advisor XE工具中的网络研讨会,并以此识别矢量化和线程化机会。

第 2 阶段
用尽了可供使用的优化解决方案后,如果还要发挥应用的更高性能,您需要启动与应用的源代码相关的优化流程。 在开展活动并行编程之前,您需要确保应用在进行向量化和并行化处理之前可提供正确的结果。 同样重要的是,您需要确保应用能够以最少的运算得到正确的结果。 您要考虑数据和算法相关的问题,如:
选择合适的浮点精度
选择合适的估算法准确度:多项式或有理数
避免跳跃算法
利用迭代计算缩短循环运算长度
避免或最大程度减少算法中的条件分支
避免重复计算,使用之前的结果
您还必须处理语言相关的性能问题。 如果您使用的是 C/C++,与该语言相关的问题包括:
对所有常量使用外显式型态法 (explicit typing),以避免自动升级
选择正确的 C 运行时函数类,比如 doubles 或 floats: exp() 与 expf();abs() 与 fabs()
以显性方式将点别名告知编译器
显式调用内联函数,以避免开销

第三阶段
尝试矢量级并行化…查看全文
了解更多相关内容,请关注CSDN英特尔开发专区

Intel技术双周刊已全面开启:订阅请点击这里

评论