本系列将主要介绍在Intel® MIC多核架构上运行及优化OpenMP*多线程程序的相关技术,且将围绕offload及native两种运行时执行环境展开详解。OpenMP编程模型包含了众多调优的编程接口及环境变量设置,本文将就此继续介绍如何更好地实现程序的高效运行。
1、使用offload模式时设置MIC_ENV_PREFIX来将Host环境的设置传播至MIC(target)计算节点
2、offload模式的多种关键字
3、使用-openmp-report来了解编译器对程序中OpenMP区域的优化处理
4、在不确定offload区域正在Host还是target上计算运行时,用户可以通过在代码中加入显示当前正执行的线程数目的方法来确定
5、OepnMP在Offload及Native模式下的不同缺省值
6、通过OMP_STACKSIZE设置OpenMP的的栈空间
【1-6详见本系列的第一、二篇:‘使用OpenMP*库的编程及调优实践(1)’、‘在Intel® MIC多核架构上使用OpenMP*库的编程及调优实践(2)’】
7、线程亲和度Affinity设置
Affinity的设置对算法的性能有重要的影响,所以理解可用的Affinity设置及算法的行为将有助于更好地通过调优线程在目标处理器上的Affinity来最优化性能。硬件线程在MIC结构上以处理器核为单位分组,且每个核上的所有硬件线程共享此处理器上的资源,所以理解算法的行为在这种情况下可更好地助于通过调优Affinity来优化处理器上资源的使用。用户可通过KMP_AFFINITY环境变量或kmp_set_affinity函数调用来设置亲和度。
亲和度起始于目标处理器上运行的初始OpenMP主线程,Offload的程序将继承其亲和度的map,且此时affinity map中不会出现最后一个核,因为其被用来处理Offload系统服务;Native程序则可以使用所有核。一些算法利用在多线程间共享数据来通过更好地利用高速缓存来加速计算,其它算法则可能只访问一次数据,从而需要线程尽量分散到不同核上来最大化利用可用带宽。OMP_NUM_THREADS及KMP_AFFINITY环境变量可以帮助用户来设置对应的线程亲和度:
export MIC_ENV_PREFIX=MIC export MIC_OMP_NUM_THREADS=60 export MIC_KMP_AFFINITY=verbose,granularity=fine,scatter
当目标处理器为31个核时,Offload程序此时将会限制硬件线程数为可用的所有硬件线程的一半且所有的运行线程将会被平均地分布于所有核上。通过设置MIC_ENV_PREFIX用户能够有选择地设置运行时线程的数量及分布策略。此时granularity被设置于fine,从而保证每一个OpenMP硬件线程将会与每个核上的硬件线程绑定在一起。
AFFINITY设置为COMPACT或SCATTER时,OpenMP线程将会集中分布于尽可能少的核上或广泛分布从而保证相邻线程运行于不同的核上。有时,将一部分线程分布于多核上且剩下的相邻线程分配于同一核上也是有优势的,此时的亲和度affinity类型为BALANCED。如以上例子中设置的verbose可以助于判断当前的所有运行线程是如何分布的,下面本文将运行一个设置有以上策略的Offload程序来具体分析几种亲和度的运行行为:
AFFINITY: fine, compact
AFFINITY: fine, scatter
AFFINITY: fine, balanced
因为此时MIC_OMP_NUM_THREADS设置为60且总共有31个核,所有最后的一个核只分配到一个线程。同样地,当MIC_OMP_NUM_THREADS设置为62时,第59个线程将会运行于核29,第60及61个线程将运行于核30。在Native方式执行时,由于此时最后一个核也可以用来计算,所有此时可以设置OMP_NUM_THREADS为64以便能保证每个核上都有两个运行线程。
用户也可以通过调用底层的affinity设置的API来调优affinity map从而更好地利用处理器架构上的计算资源。
8、利用KMP_PLACE_THREADS环境变量来分配部分计算资源给运行的程序
为了分析程序的可扩展性我们可以改变程序可使用的核数。例如,可用KMP_PLACE_THREADS=30c,2t来指定程序运行于30个核上且每个核上执行两个线程,此时再用KMP_AFFINITY=scatter或KMP_AFFINITY=compact设置线程在核间的分布策略来进一步调优。且由于OpenMP运行时会缺省使用所有的硬件线程,所以OMP_NUM_THREADS不需要再显式地设置。
所以当显式地指定OMP_NUM_THREADS及KMP_PLACE_THREADS时,要格外注意是否手动设置的OpenMP线程数大于可用的硬件线程数:如果大于,则会出现over-subscription的情况从而导致性能下降;如果小于的话,则会因为硬件线程分配不平均的问题也会出现性能达不到最优的情况。
Period.