OpenMP并行化优化
2.1 0penMP工作原理简介
OpenMP是一个基于共享内存模式的跨平台多线程并行的编程接口。主线程生成一系列的子线程,并将任务映射到子线程进行执行,这些子线程并行执行,由运行时环境将线程分配给不同的物理处理器。默认情况下,各个线程独立执行并行区域的代码。可以使用work-sharingconstructs来划分任务,使每个线程执行其分配部分的代码。通过这种方式,使用OpenMP可以实现任务并行和数据并行。
图2 任务并行模型
任务并行模式创建一系列独立的线程,每一个线程运行一个任务,线程之间相互独立,如图2所示。OpenMP使用编译原语session directive和task directive来实现任务分配,每个线程可以独立运行不同的代码区域,同时支持任务的嵌套和递归。一旦创建任务,该任务就可能会在线程池(其大小等于物理线程数目)中空闲的线程上执行。
数据并行也就是数据级并行,对任务中处理的数据进行分块并行执行,如图3所示。C语言中的for循环最适合使用数据并行。
图3 数据并行模型
2.2 快速排序算法原理
快速排序算法是一种递归分治算法,算法中最为关键的就是确定哨兵元素(pivot data)。数据序列中小于哨兵的数据将会放在哨兵元素的左侧,序列中大于哨兵的数据将会被放在哨兵元素的右侧。当完成数据扫描后,哨兵元素分成的左右两个部分就会调用快速排序算法递归进行。
快速排序算法中涉及算法的递归调用,会产生大量任务,并且这些任务相互独立,非常适合OpenMP的任务并行模式;另外,就一次快速排序搜索算法而言,哨兵元素对于左右子区间数据容量大小具有决定性作用,考虑到嵌入式平台的缓存(Cache)空间较小,需要对哨兵元素筛选算法进行优化,尽量使得划分出来的左右子区间更均衡,满足负载均衡的要求。
2.3 任务并行化优化
通过对快速排序算法的分析,快速排序是一个递归调用算法,算法的执行过程中会产生大量重复函数调用,并且函数的执行相互独立。对于快速排序的一次扫描运算而言,算法首先确定哨兵元素(pivot),并对数据序列进行一次调整,然后对哨兵元素的左右区间再次进行递归调用算法。
如下所示,对任务并行化优化针对每次扫描调整后的左右子区间,将每个子区间的运算抽象为一个任务,并通过OpenMP中的任务并行化原语#pragma omp task实现任务的并行化执行,从而实现了快速排序的任务并行化优化。
任务空间中的数据大小取决于哨兵元素,因此,算法选取的划分算法(Partition Algorithm)应尽量将数据序列的划分均衡化,本文使用简单划分算法和三元中值法(Median-of-Three Method)进行测试。
2.4 缓存优化
缓存优化(Cache friendly)的目标是减少数据在内存和缓存之间的拷贝。对于220个整型数据而言,数据大小为4 MB,本文的测试平台()MAP4430的二级缓存为1 MB,需要将数据划分为4个部分。
如下所示,算法将4部分数据分为4个快速排序任务,4部分任务并行执行,完成后每部分数据序列排序完成,需要将4部分数据进行合并形成完成数据序列,因此在并行任务结束后,需要对数据进行归并排序。
OpenMP并行化优化
2.1 0penMP工作原理简介
OpenMP是一个基于共享内存模式的跨平台多线程并行的编程接口。主线程生成一系列的子线程,并将任务映射到子线程进行执行,这些子线程并行执行,由运行时环境将线程分配给不同的物理处理器。默认情况下,各个线程独立执行并行区域的代码。可以使用work-sharingconstructs来划分任务,使每个线程执行其分配部分的代码。通过这种方式,使用OpenMP可以实现任务并行和数据并行。
图2 任务并行模型
任务并行模式创建一系列独立的线程,每一个线程运行一个任务,线程之间相互独立,如图2所示。OpenMP使用编译原语session directive和task directive来实现任务分配,每个线程可以独立运行不同的代码区域,同时支持任务的嵌套和递归。一旦创建任务,该任务就可能会在线程池(其大小等于物理线程数目)中空闲的线程上执行。
数据并行也就是数据级并行,对任务中处理的数据进行分块并行执行,如图3所示。C语言中的for循环最适合使用数据并行。
图3 数据并行模型
2.2 快速排序算法原理
快速排序算法是一种递归分治算法,算法中最为关键的就是确定哨兵元素(pivot data)。数据序列中小于哨兵的数据将会放在哨兵元素的左侧,序列中大于哨兵的数据将会被放在哨兵元素的右侧。当完成数据扫描后,哨兵元素分成的左右两个部分就会调用快速排序算法递归进行。
快速排序算法中涉及算法的递归调用,会产生大量任务,并且这些任务相互独立,非常适合OpenMP的任务并行模式;另外,就一次快速排序搜索算法而言,哨兵元素对于左右子区间数据容量大小具有决定性作用,考虑到嵌入式平台的缓存(Cache)空间较小,需要对哨兵元素筛选算法进行优化,尽量使得划分出来的左右子区间更均衡,满足负载均衡的要求。
2.3 任务并行化优化
通过对快速排序算法的分析,快速排序是一个递归调用算法,算法的执行过程中会产生大量重复函数调用,并且函数的执行相互独立。对于快速排序的一次扫描运算而言,算法首先确定哨兵元素(pivot),并对数据序列进行一次调整,然后对哨兵元素的左右区间再次进行递归调用算法。
如下所示,对任务并行化优化针对每次扫描调整后的左右子区间,将每个子区间的运算抽象为一个任务,并通过OpenMP中的任务并行化原语#pragma omp task实现任务的并行化执行,从而实现了快速排序的任务并行化优化。
任务空间中的数据大小取决于哨兵元素,因此,算法选取的划分算法(Partition Algorithm)应尽量将数据序列的划分均衡化,本文使用简单划分算法和三元中值法(Median-of-Three Method)进行测试。
2.4 缓存优化
缓存优化(Cache friendly)的目标是减少数据在内存和缓存之间的拷贝。对于220个整型数据而言,数据大小为4 MB,本文的测试平台()MAP4430的二级缓存为1 MB,需要将数据划分为4个部分。
如下所示,算法将4部分数据分为4个快速排序任务,4部分任务并行执行,完成后每部分数据序列排序完成,需要将4部分数据进行合并形成完成数据序列,因此在并行任务结束后,需要对数据进行归并排序。
举报