并行计算的内存访问方法

文档序号:6600249阅读:271来源:国知局
专利名称:并行计算的内存访问方法
技术领域
本发明涉及计算机技术,特别是涉及多线程的PDF格式文件操作中的内存访问控制;以及由此引申出来的多线程并行计算时的内存访问策略和提高运行效率的方法。
背景技术
图书、图片、文件等实体资源的数字化通常是采用扫描——识别——提取的方式。 先将文档扫描为PDF格式,再进行文档模块和文字的识别,之后提取识别后的信息,供编档 和供给搜索引擎以供建立索引。现有技术中,对大量的PDF格式的文档进行操作时,往往需 要大量的系统资源,包括CPU和内存资源,并且对PDF格式文档的处理速度也较慢。为了提 高处理速度,各种方式被选用,特别是近年来随着多核处理器技术的成熟,在多个CPU上同 时运行多个线程成为提高计算速度的首选方式之一。然而,实际操作中,却往往出现速度提高有限,而同时CPU却不能被完全利用的情 况。例如,如果充分利用CPU,那么在多核机器上,例如4核CPU上测试,开4个线程,做压力 测试的时候,每个线程占用一个CPU,理论上CPU占用率应该是接近100%的。但是在实际 的测试中发现,CPU占用率远低于100%,甚至很多时候,CPU占用率只达到25%。这说明, 并非每个CPU都在工作,这里应该是有线程等待。CPU并没有得到充分的利用。本案发明人结合自身多年业内工作经验和实验结果对此现象的成因进行了分析 和研究,并最终得出该情况的发生主要在于对内存操作工程中,无论是内存的分配和释放 都需要线程保护,且所有的线程共享一个内存池,从而导致了访问等待,使CPU无法被充分 利用。而PDF操作对内存是非常频繁的操作,所以引起了大量的线程等待。关于内存访问,在传统操作系统的内存管理中,多是将每个应用程序加载到一个 单独的进程,并为每一进程指定私有的内存空间,内存空间在进程间不能互访。一般来说, 一个应用程序进程运行时会创建多个实体,即线程,同属一个进程的多个线程共享该进程 的资源。随着计算技术和硬件的发展,特别是近年来多核处理器的广泛应用,线程的并发 执行(并行计算)越来越普遍。在多个线程并行时,考虑到数据安全,其对共享内存的访问 往往是逐一进行而不能同时访问,即便允许同时访问也经常会有分配的内存池容量不够多 个线程之用的情况,这就造成了内存访问的等待。特别是在使用多CPU,每个CPU运行一个 线程的情况,当CPU处理所需时间小于内存访问和等待时间时,内存访问就成了计算速度 的瓶颈,使得CPU资源无法得到充分的利用,妨碍了计算速度的进一步提高。为了改善内存访问,本领域技术人员提出了多种方法。例如,专利授权公告号 CN100487660C,名为“一种多线程处理器动态内存管理系统及方法”的中国发明专利公开了 一种多线程处理器动态内存管理方法,参见图1,该方法包括以下步骤主控内核线程从系 统内存中申请一段内存作为内存池(步骤101);所有内核线程向所述主控内核线程发送申 请内存消息,主控内核线程收到所述申请内存消息后,从所述内存池中分配空闲的内存给 申请内存的内核线程,并向申请内存的内核线程发送分配内存消息(步骤102);所述主控内核线程查询内核线程已申请的内存的使用情况,定期发送回收内存消息(步骤103);内 核线程收到所述回收内存消息后,对内存进行归还,并向主控内核线程发送释放内存消息 (步骤104)。该方法在一定程度上解决了内核线程的内存释放问题,能够避免某一时刻某一空 闲的内核线程占用过多的空闲内存。由主控内核线程取代硬件仲裁器,利用消息机制,提高 了内存在各个内核线程间的分配使用效率。但是该方法却无法解决共享一个内存池的多个 线程均请求较大内存空间而必须排队等候的问题。并且应用此方法,要改变内存管理代码, 并不适合代码的直接移植。

发明内容
本发明的目的在于,针对多个线程调用同一个执行模块时,由于必须共享同一内 存池,且该内存池无法提供足够资源而导致内存访问等待时间过长的问题,提供一种新的 内存访问策略,以缩短甚或消除并行计算时的内存访问等待时间,使单个线程能够拥有独 立的内存池。更重要的目的是,要能在不改变或很少改变模块代码特别是完全不改变内存管理 的情况下,将单线程代码,简单移植到多线程环境中。并让多核多线程的优势得到充分发 挥。本发明的并行计算的内存访问方法,用于存在调用同一原始执行模块的n > 2个 并行线程的情况,其特征在于,包括以下步骤S 1)根据线程数n确定需创建的映像执行模块的个数k,n-1彡k彡1 ;S2)确定该n个线程与原始执行模块及k个映像执行模块之间的映射策略F ;S3)创建k个映像执行模块,并为其分配各自私有的内存池;S4)执行所述并行的n个线程,令各个线程按照所述映射策略F调用执行模块,每 个执行模块访问且仅访问其私有的内存池;S5)线程运行完成后删除创建的映像执行模块,释放资源。其中,所述映像执行模块的个数为k可以是随时间变化的。或者,所述映像执行模 块的个数k在线程执行期间也可是固定不变的。较佳地,可根据同一时间调用同一执行模块的线程个数的统计值来确定映像执行 模块的数量。根据本发明的一实施例,所述映像执行模块的个数k为1个。根据本发明的另一实施例,所述映像执行模块的个数k为n-1个。其中,当所述映像执行模块的个数k为n-1个时,所述映射策略F可为每个线程 分别调用一个不同的执行模块,线程与执行模块是一一对应的。根据本发明的再一实施例,所述映射策略F可为静态策略,一个线程仅指向一个 被它调用的执行模块,而一个执行模块被一个或一个以上的线程调用。较佳地,所述映射策略F为将调用执行模块频繁的线程,配置为独享一个执行模 块,将相对调用执行模块频率较低的线程,配置为共享执行模块。根据本发明的又一实施例,所述映射策略F为动态策略的“多窗口排队”机制,该 策略F中,为每个执行模块定义“空闲”、“繁忙”两个状态,将所有的空闲执行模块排队,需
4要调用执行模块的线程从空闲执行模块队列中择一调用,若没有空闲的则等待;在线程对执行模块的调用进行中将该执行模块标记为繁忙,执行完毕后,线程释放该执行模块,将其 标记为空闲。应用本发明的方法可令并行计算的效率随核心数增加而呈线性增长,而不受内存 访问瓶颈的限制。对各种操作系统均可适用。并且,使用静态方式时,甚至无需增加代码, 即可将单线程的程序直接移植到多线程环境。而灵活的动态方式和动态映射策略,则可使 本发明在占用不是那么多的系统资源的情况下显著提高效率,事半功倍。


图1是现有技术的一种内存管理方法的流程图;图2是多个线程均调用同一执行模块时的内存访问示意图;图3是为多个线程分别创建各自的执行模块时的内存访问示意图;图4是本发明的内存访问方法优选实施例的流程示意图;图5是使用本发明的方法与使用其它措施时的线程性能比较示意图一;图6是使用本发明的方法与使用其它措施时的线程性能比较示意图二 ;图7是使用本发明的方法与使用其它措施时的线程性能比较示意图三。
具体实施例方式本发明目的在于在不改变操作系统的内存管理的前提下改变内存访问方式。为对 便于对本发明进行更好的理解,首先对一般的内存管理方式进行说明。内存管理的特点之一是执行模块是隔离的,每一个执行模块被分配独立的内存池 空间。其中,执行模块可视为是系统在内存中建立的一个个数据结构,用于管理运行时加载 到内存中的程序代码,数据以及资源。每个执行模块作为一个系统资源的分配单位,享有其 独自的内存池,执行模块中的多个函数将共享该执行模块的内存池。所述执行模块可以是运行后被加载到进程中的一个windows下的.exe程序或一 个动态链接库(dll)等。同一个执行模块,不论多少个线程在调用,只会被加载一次,由同 一个进程开启的所有线程,对于同一执行模块,它的内存池是共享的。依操作系统类型的不 同,执行模块还可有其它形式。按照本领域技术人员的公知,不同的操作系统的内存管理模 式会有区别,但是均会存在这样一种特定的单元,其由一些数据和代码的集合构成,表现为 程序、函数等形式,并且对该种代码组合操作系统会分配私有的(private)内存空间(包括 逻辑的或物理的)以供其访问。因此,在本发明中,执行模块也可理解为在给定操作系统 下,依据该操作系统的默认内存管理方式而为其分配单独的内存池的一组代码和数据的集
口 o图2示出了多个线程用到了同一个执行模块情况下的内存访问情况。其中进程 1(211),进程2 (212)……进程n (213)等为某一应用程序的多个并行线程,它们均需要调用 一执行模块220,执行模块220访问内存池230。在此类多线程环境下,当多个线程(211到213)同时调用一个执行模块(220)的 时候,如果在执行模块中多个线程同时需要对内存进行操作(例如申请和释放),即同时对 同一个内存池操作,则线程对内存的访问需要排队,从而由内存引起了线程的等待,导致无法充分利用CPU资源。这也正是本发明意欲解决的问题所在。图3显示了本发明为解决上述问题而为每个线程分别创建各自的执行模块时的内存访问示意图。以n个线程为例(n为自然数),默认情况下(参见图2),系统只有一个 原始执行模块1 (321),而在本发明中,根据进程数量,额外创建了 n-1个映像执行模块,即 执行模块2(322)到执行模块n (323),从而使执行模块的总数量与线程总数相等。其中,映 像执行模块可以由原始执行模块1复制而得,功能与原执行模块相同。此时,对于操作系统 而言,由于其默认地会为每个执行模块分配单独的内存池,因此各个执行模块分别访问各 自不同的内存池,互不干扰。例如图3所示的执行模块1(321)访问内存池1(331),执行模 块2 (322)访问内存池2 (332),……,执行模块n (323)访问内存池3 (333)。从而在不改变 操作系统和内存管理代码的前提下,实现了使每个线程拥有单独的内存池。这样,在需要内 存操作的时候,各个线程不需要抢占同一个内存池,也就无需等待。简而言之,本发明通过复制执行模块的方法实现多线程下每个线程使用独立的内 存池管理。使共享资源变成了独享资源,以空间换取时间,避免了由线程间内存访问冲突带 来的等待。本实施例以空间换时间的最典型例子。该解决方法在不改变或很少改变模块代 码,特别是能在完全不改变内存管理的情况下,将单线程代码简单的移植到多线程环境中, 可以说是解决并行计算效率问题的万能方法。要强调的是,对n个线程而言,创建的映像执行模块的数量不一定要是n-1个,其 可以是从1到n-1之间的任意数量。因为,从上面的分析可以明确,映像执行模块的目的在 于缓解内存访问的排队现象。这就好比在服务窗口排队的情形,当n个顾客只能通过一个 窗口获得服务时时,效率低,等待时间的数学期望长;而再增加一个窗口(k=l)即可使整 个排队等待时间的显著降低;创建n-1个映像执行模块则可使期望排队时间降为0。可见 图3所示的实施例是以减小线程内存访问的排队等待时间为目的时的一个优选实施例,而 不能作为对本发明实施方式的限制。下面结合具体的图4的具体流程,对本发明的方法进行进一步的说明。总体上说, 本发明的映像执行模块的创建可以分为动态方式和静态方式两类。其中,静态方式是指线 程与各个执行模块之间的对应拓扑映射策略在整个程序执行过程中该线程的生命周期内 是固定不变的;而动态方式中,映像执行模块的数量提及线程与各个执行模块之间的映射 策略可以改变。图4是本发明的内存访问方法优选实施例的流程示意图。其中,从开始到结束的 过程可以是代表一个应用程序的始末;也可以是表示一组需调用同一原始执行模块的线程 的生命周期等执行过程。其可依本发明的应用场合而定,本领域技术人员可自行根据不同 的应用做出选择,并不构成对本发明的限制。为叙述方便,下文中以te
来表示从开 始到结束过程中的任意时间点,t = 0为开始,t = T为结束。作为统称,执行模块包括原始 执行模块和映像执行模块。其中,所述映像执行模块与原始执行模块执行相同的功能,但被 分配使用不同的系统资源(例如CPU和内存空间)。首先,在步骤410获取需调用同一原始执行模块的并行的线程的数量n,n为自然 数。然后,在步骤420,对n进行判断,在n= 1时,只有一个线程,该线程与执行模块是唯一 对应的,不会发生由排队导致的内存访问等待,转到步骤460直接执行该线程即可。当2时,代表可能会发生等待,需要创建映像执行模块来改善内存访问。一般来说,线程的数量 n的设置与计算设备CPU的核心数有关。接下来,执行步骤430,确定需新创建的映像执行模块数k,k为自然数且优选地,
其中,创建n-1个映像执行模块的情况参见图3所示,此时相当于以最大的空 间来换取最高的时间效率。而在其它数值之间选择,则是空间和时间二者折衷的结果。本 领域技术人员可以在本发明的教导下根据实际的应用环境进行选择。例如,当并行的线程 数量太多,而总的内存空间有限,如果创建过多的映像执行模块将影响其它程序的运行或 显著降低系统的整体效能,甚至是内存空间根本不够建立那么多的映像执行模块时,都需 要减少映像执行模块的数量。再比如,可根据线程同时调用同一执行模块的概率来确定映 像执行模块的数量,所述概率大时创建较多的映像执行模块;以及根据同一时间调用同一 执行模块的线程个数的统计值(例如最大值、中值或数学期望)来确定执行模块的数量。选择静态方式一种简捷的实施方式。其中,k为固定值,k(t)在t e
是保 持不变的。静态方式的好处在于,程序执行简单,占用内存空间固定,利于稳定执行。不足 之处是当进程执行过程中对执行模块的调动频率波动较大时,如果选择大的k值可能会造 成内存空间的浪费,而选择较小的k值又可能会导致在调用频繁的时段发生内存访问的等待。动态方式则较为灵活。k(t)在t G
是可变的,根据进程执行过程中对执行 模块的调动频率,k(t)可以设为分段函数。在多个线程对执行模块频繁的时段,选择较大 的k(t)值,而在相对来说调用执行模块较少的时段,则选择较小的k(t)值。在进程的执行 过程中灵活改变,从而及时释放资源,避免造成内存空间的浪费。但是动态方式的不足之处 在于访问控制稍嫌复杂,并且会存在参数传递等问题,需要另外增加代码,不利于单线程程 序向多线程程序的直接移植。在步骤440,确定该n个线程与原始执行模块及k个映像执行模块之间的映射策略F.所述映射策略F主要体现的是哪一个线程调用哪一个执行模块这样的单向关系。 同样,映射策略F也分为静态策略和动态策略。其中,对于静态策略,一个线程仅指向一个 被它调用的执行模块,而一个执行模块可被一个或一个以上的线程调用。且这种调用关系 在t e
时间段内保持不变。静态策略执行简单,无需过多的额外代码。进一步较佳的是,对于那些调用执行模块频繁的线程,可以配置为独享一个执行 模块,而对相对调用执行模块较少的线程,配置为共享执行模块。而对于动态策略,线程可以并不固定指向某一个执行模块。例如可以配合映像执 行模块的动态方式而将映射策略F也做分段设置,将时间t e
分成几个时间段,在每 个时间段中使用静态策略。或者还可以采取一种类似“多窗口排队”的机制等多种不同的 方式。根据本发明的一实施例,为每个执行模块定义“空闲”和“繁忙”两个状态分别对 应不同的调用状态。将所有的空闲执行模块排队,第一个需要调用执行模块的线程调用空 闲执行模块队列的第一个;每当有新的线程要调用执行模块时,令其调用空闲执行模块队 列中的下一个,若没有空闲。在线程对执行模块的调用进行中将该执行模块标记为繁忙,执 行完毕后,线程释放该执行模块,将其标记为空闲。这种排队机制的好处是可以最大限度的充分利用资源,特别是对k<n_l的情况,既能从总体上节约内存资源,又能有效避免有资 源闲置情况下却发生内存访问等待的情况。特别适用于线程较多,而且线程对执行模块的 调用随机性较强的情况,用本实施例的方法可以用较少的内存映像模块来实现效率的大幅提尚。显然,各种映像模块的静态方式和动态方式与映射策略F的静态策略和动态策略 可以相互组合而构成各种灵活的内存访问控制策略。其具体实施的步骤,在上述本发明内 容的教导下,本领域技术人员当可自行实现。要注意的是,无论怎样的组合和变换,只要未 脱离本发明的精神实质,均将落入所附权利要求书所限定的范围。之后进行步骤450,创建k个映像执行模块,并为其分配各自独立的内存池。这一 步中,映像执行模块创建之后,内存分配实际上是由操作系统控制完成的,并不需要应用程 序的干预。在映像执行模块完成之后,接着进行步骤460,执行所述并行的n个线程,并令其 按照所述调用映射策略F调用执行模块。在执行过程中,每个执行模块访问且仅访问其私 有的内存池。最后是步骤470,线程运行完成后删除所有创建的映像执行模块,释放为映像执行 模块分配的资源。图5到图7显示了依据本发明的方法进行内存访问控制后的性能与不使用本发明 时的比较,通过以下示例体现。要说明的是,以下示例仅是为了说明本发明的效果,而非对 本发明的实施条件进行限制。以windows操作系统为例,通过对pdf文件进行简单文字提取来进行测试。测 试环境软件环境 Windows XP professional SP2 32bit,硬件环境 Core 2 QuadQ6600 2. 4GHz (4core) 3. 25GB 内存。测试工具使用微软公司发布的platform sdk中的ifilttst. exe测试工具程序 ifilttst. exe,该程序仅仅对文件进行一次完整提取,并不进行更多的检查性工作。关于 该测试工具为本领域公知常用的一种,关于其详细资料,可参考httP://mSdn. microsoft. com/en-us/1 ibrary/ms692580 (28VS. 85). aspx 上的说明。ifilttst. exe可对应创建不同数量的线程,在运行中,各个线程会调用一执行模 块example, dll。在图5到图7中的横坐标1,2,3,4表示线程数,对应的使用多个不同的 处理器核心运行。纵坐标用文件处理速度表示的性能指数。不同的曲线分别表示针对使用 本发明的方法和不使用时的执行情况。其中,本发明的方法的实施方式为对不同的线程数 n,分别创建k = n-1个映射执行模块,且采用静态方式下的静态映射策略。即每个线程指 向一个执行模块,且在整个执行过程中保持不变。图5的实施例中,样本1为219个文件,总大小1. 54GB,特点文件较大,文件个数 较少。图6的实施例中,样本2为351个文件,总大小1. 16GB,文件数目和每个文件的大 小较为平均。图7中的样本3为1274个文件,总大小925MB,文件数目多而且体积较小。在图5-7中,曲线L1为ifilttst. exe使用本发明方法时的执行情况;曲线L2为 ifilttst. exe未使用本发明加速方法前的运行情况。
从图5到图7可以看到,测试工具程序ifilttst. exe的单线程性能虽然没有提 高,但是多线程的性能正真得到了释放,每个核心都被利用了起来,1到4线程时,性能呈线 性增长。而未采用本发明加速方法的曲线L2,虽然随着CPU核心的增加性能也有所改进,却 无法将CPU性能发挥到最佳,性能始终受到限制。以上对本发明的描述是说明性的,而非限制性的,本专业技术人员理解,在权利要 求限定的精神与范围之内可对其进行许多修改、变化或等效,但是它们都将落入本发明的 保护范围内。
权利要求
一种并行计算的内存访问方法,用于存在调用同一原始执行模块的n≥2个并行线程的情况,其特征在于,包括以下步骤S1)根据线程数n确定需创建的映像执行模块的个数k,n-1≥k≥1;S2)确定该n个线程与原始执行模块及k个映像执行模块之间的映射策略F;S3)创建k个映像执行模块,并为其分配各自私有的内存池;S4)执行所述并行的n个线程,令各个线程按照所述映射策略F调用执行模块,每个执行模块访问且仅访问其私有的内存池;S5)线程运行完成后删除创建的映像执行模块,释放资源。
2.根据权利要求1所述的并行计算的内存访问方法,其特征在于,所述映像执行模块 的个数为k是随时间变化的。
3.根据权利要求1所述的并行计算的内存访问方法,其特征在于,所述映像执行模块 的个数k在线程执行期间是固定不变的。
4.根据权利要求3所述的并行计算的内存访问方法,其特征在于,根据同一时间调用 同一执行模块的线程个数的统计值来确定映像执行模块的数量k。
5.根据权利要求3所述的并行计算的内存访问方法,其特征在于,所述映像执行模块 的个数k为1个。
6.根据权利要求3所述的并行计算的内存访问方法,其特征在于,所述映像执行模块 的个数k为n-1个。
7.根据权利要求6所述的并行计算的内存访问方法,其特征在于,所述映射策略F为 每个线程分别调用一个不同的执行模块,线程与执行模块是一一对应的。
8.根据权利要求1所述的并行计算的内存访问方法,其特征在于,所述映射策略F为静 态策略,一个线程仅指向一个被它调用的执行模块,而一个执行模块被一个或一个以上的 线程调用。
9.根据权利要求8所述的并行计算的内存访问方法,其特征在于,所述映射策略F为将 调用执行模块频繁的线程,配置为独享一个执行模块,将相对调用执行模块频率较低的线 程,配置为共享执行模块。
10.根据权利要求1所述的并行计算的内存访问方法,其特征在于,所述映射策略F为 动态策略的“多窗口排队”机制,该策略F中,为每个执行模块定义“空闲”、“繁忙,,两个状 态,将所有的空闲执行模块排队,需要调用执行模块的线程从空闲执行模块队列中择一调 用,若没有空闲的则等待;在线程对执行模块的调用进行中将该执行模块标记为繁忙,执行 完毕后,线程释放该执行模块,将其标记为空闲。
全文摘要
本发明涉及一种并行计算的内存访问方法,用于存在调用同一原始执行模块的n≥2个并行线程的情况,包括以下步骤S1)根据线程数n确定需创建的映像执行模块的个数k,n-1≥k≥1;S2)确定该n个线程与原始执行模块及k个映像执行模块之间的映射策略F;S3)创建k个映像执行模块,并为其分配各自私有的内存池;S4)执行所述并行的n个线程,令各个线程按照所述映射策略F调用执行模块,每个执行模块访问且仅访问其私有的内存池;S5)线程运行完成后删除创建的映像执行模块,释放资源。本发明可令并行计算的效率随核心数增加而呈线性增长,而不受内存访问瓶颈的限制。各种操作系统通用,且便于将单线程的程序直接移植到多线程环境。
文档编号G06F9/50GK101799773SQ20101014050
公开日2010年8月11日 申请日期2010年4月7日 优先权日2010年4月7日
发明者林芝, 熊雨前 申请人:福州福昕软件开发有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1