首页> 中国专利> 一种多核多线程环境下NUMA感知的同步方法

一种多核多线程环境下NUMA感知的同步方法

摘要

本发明公开了一种多核多线程环境下NUMA感知的同步方法,属于并行计算领域。本发明提出的方法是:线程将同步请求结点插入链表并在局部锁上自旋,如果局部锁被释放并且请求已被执行则返回,否则该线程作为combiner线程,设置宿主NUMA节点,执行请求的回溯位置,然后开始执行自己以及其他线程的同步请求,执行完毕后从当前位置向前遍历寻找来自宿主NUMA节点内的线程,若找到则将其作为新的combiner线程并通知该线程回溯位置,否则将当前位置的下一个线程作为combiner线程。在多线程竞争访问共享资源,并且共享资源访问模式较为分散的情况下,多个NUMA节点之间的跨节点通信和远程内存访问的开销较大。本发明有效降低了该开销,提高了多线程应用程序在多核系统上的运行效率。

著录项

  • 公开/公告号CN104834505A

    专利类型发明专利

  • 公开/公告日2015-08-12

    原文格式PDF

  • 申请/专利权人 华中科技大学;

    申请/专利号CN201510240609.0

  • 发明设计人 吴松;金海;张俊;

    申请日2015-05-13

  • 分类号G06F9/38(20060101);

  • 代理机构42201 华中科技大学专利中心;

  • 代理人曹葆青

  • 地址 430074 湖北省武汉市洪山区珞喻路1037号

  • 入库时间 2023-12-18 10:12:06

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2017-04-26

    授权

    授权

  • 2015-09-09

    实质审查的生效 IPC(主分类):G06F9/38 申请日:20150513

    实质审查的生效

  • 2015-08-12

    公开

    公开

说明书

技术领域

本发明属于并行计算领域,更具体地,涉及一种多核多线程环境下NUMA感知的同步方法。

背景技术

在过去的几十年里,多核技术的巨大进步使得并行编程变得非常流行,极大的提高了应用程序的性能。然而对于那些包含大量串行部分代码的应用程序,性能并没有得到相应的提高,因为串行部分无法被并行化。串行部分一般包含可以被多个线程访问的共享资源,因而为了数据安全,这部分代码必须以互斥的方式执行。根据阿姆达尔定律,任何应用程序在并行化后能够加速的程度取决于串行部分和并行部分的比例。因此,在并行编程领域,一个高效的同步机制扮演者非常重要的角色,特别是对于需要大量同步操作的应用程序。

随着计算机处理器核心数目的日益增加,主流计算机处理器厂商已经从传统的基于总线的架构迅速转向NUMA以及cache coherent NUMA(ccNUMA)架构。NUMA架构由多个互联的节点组成,每个节点包含独立的本地内存和若干个核,每一个核有自己的私有缓存,同一个节点内的多个核共享一个最后一级缓存(LLC)。NUMA架构中,如果线程访问的数据没有在本地内存(包括这个NUMA节点内所有核的私有cache以及所有核共享的LLC)命中,将会导致跨NUMA节点的远程内存访问(RMR)和由于维持NUMA节点间的数据一致性而导致的大量跨节点通信,这个对于ccNUMA机器来说性能损失的代价是非常昂贵的。处理器核访问本地内存,特别是本地缓存的速度比访问其他NUMA节点的远端内存速度快好几倍。所有这些因素使得设计一个高 效的NUMA感知的同步机制变得非常复杂。

基于队列的思想来设计同步方法是一个被广泛使用的策略。通过让线程在一个队列里面排队,每个线程在本地自旋,可以一定程度上减少整体上为维持数据一致性而导致的缓存一致性通信开销,但是该方法在NUMA架构上却不能很好的工作,因为访问共享资源的线程可能交替来自于不同的NUMA节点,从而引起大量的远程内存引用以及跨NUMA节点间的通信,而这些都会严重影响应用程序的性能。combining技术是另外一种设计同步方法的策略,它可以有效减少私有缓存的丢失率,但是无法减少为维护数据一致性而导致的NUMA节点间通信,进来带来很大的性能损失。分层锁的设计策略是用来设计NUMA感知的同步方法的,但是该策略的挑战在于如何保证访问共享资源的权限停留在一个NUMA节点内合适的时间段。除了上面提到的问题与缺陷之外,另外一个非常重要的问题是这些方法策略并没有考虑到共享资源的访问特性,当应用程序以分散的模式来访问共享资源时会使得上述问题进一步恶化,进而带来更严重的性能下降问题。

本发明中,节点指NUMA节点,结点均指线程的同步请求结点。

发明内容

针对现有技术的以上缺陷或改进需求,本发明提供了一种多核多线程环境下的NUMA感知(aware)的同步方法,解决在共享资源的访问模式较为分散的情况下,多个NUMA节点之间的跨节点通信和远程内存访问的开销较大而导致的性能下降的技术问题。

为实现上述目的,本发明提出了一种用于在多核多线程环境下的NUMA感知的同步方法,首先对本发明的术语进行解释和说明:

宿主NUMA节点:在本发明中,线程所访问的共享数据要尽可能地保存在某一个特定的NUMA节点内的cache中,本发明定义该NUMA节点为宿主NUMA节点,在本发明中宿主NUMA节点编号初始化为-1。

combiner线程:获得访问共享资源权限的线程,其在执行自己的同步 请求后,还帮助其他线程执行它们的同步请求,本发明定义该线程为combiner线程。本发明内combiner线程以及其他所有线程都是通过调用pthread线程库的pthread_create(pthread_t*thread,const pthread_attr_t*attr,void*(*start_routine)(void*),void*arg)函数创建的。

SWAP操作:以SWAP(a,b)为例,该操作将a的值设置为b,并且返回a之前的值,同时该操作是一个原子操作。SWAP操作通过调用gcc编译器的内建函数__sync_lock_test_and_set(type*ptr,type value)来实现。

回溯位置:在本发明中,指遍历同步请求链表的起始位置。

本发明基于linux编程环境,包括以下步骤:

(1)设置参数步骤:线程设置自己的同步请求结点的相关参数,将线程的NUMA节点编号设置为空,线程的下一结点指针next设置为空,局部锁状态变量lock设置为true,同步请求执行标记completed设置为false;然后获取同步请求链表尾指针PT;

(2)插入同步请求结点步骤:线程将自己的同步请求结点插入当前系统内的同步请求链表的末尾处;

(3)负载判别步骤:线程在指针变量current指向的结点的局部锁上面自旋,同时判别当前等待访问临界区的线程数目是否大于计算机内的处理器核的数目,是则调用linux库函数sched_yield(),暂时放弃处理器的使用权,该库函数执行返回后继续自旋;否则线程就继续自旋;一旦局部锁被释放则自旋结束进入步骤(4);

(4)执行判别步骤:判别当前线程的同步请求是否已经被执行,是则转入步骤(9),否则进入步骤(5);

(5)设置节点编号步骤:判别标志宿主NUMA节点编号是否被设置过,是则不作处理,转步骤(6);否则设置其值为当前线程所在的NUMA节点的编号,转步骤(6);

(6)设置回溯位置步骤:设置指针变量p来存储指针变量current值;

判别指针变量p指向的结点线程的回溯位置是否非空,是则将指针变量p指向所述回溯位置,然后将指针变量p原来的回溯位置设置为空,进入步骤(7);否则不作处理,转步骤(7);

(7)遍历并服务同步请求链表步骤,此时将当前线程作为combiner线程;

(8)选择下一个combiner线程;

(9)结束步骤:当前线程的任务完成,返回同步请求的执行结果。

优选地,步骤(2)具体包括以下子步骤:

(2.1)使用原子操作SWAP将同步请求链表尾指针PT指向本线程当前的同步请求结点,SWAP返回操作前同步请求链表尾指针并将其赋值给指针变量current;

(2.2)计算出指针变量current所指向的结点所在的NUMA节点的编号; 

(2.3)将指针变量current所指向结点的next指针指向刚刚插入的那个结点;

优选地,步骤(7)包括以下子步骤:

(7.1)从指针变量p所指向的结点开始遍历同步请求链表,如果同步请求链表中指针变量p指向的结点的指针next非空,且标志当前线程所服务的同步请求的数量的局部计数器的值未超过计数上限值M,则进入(7.2);否则转步骤(8);M为当前线程数目的3-10倍;

(7.2)根据指针变量p指向的结点的next,将next值用指针变量tmp_next暂存;

(7.3)将局部计数器的值加1;

(7.4)为指针变量p指向的结点线程执行其同步请求,将该线程同步请求执行标记completed设置为true;

(7.5)将指针变量p指向的结点线程的局部锁lock设置为false,释放该局部锁lock;

(7.6)将指针变量tmp_next赋给指针变量p,转向步骤(7.1);优选地,步骤(8)包括以下子步骤:

(8.1)判别指针变量p指向结点是否为尾结点,是则将尾结点的lock设置为false,然后转向步骤(9);否转子步骤(8.2);

(8.2)判别指针变量p指向的结点的NUMA节点编号是否为宿主NUMA编号,是则将指针变量p指向的结点线程的lock设置为false,此时该线程作为combiner线程,然后进入步骤(9);否则转子步骤(8.3);

(8.3)将指针变量p的值赋值给指针变量p1,从指针变量p指向的结点开始,沿着其next指针向下遍历各个结点,判别是否找到某结点的NUMA节点编号为宿主NUMA节点编号,是则进入子步骤(8.4);否则转入子步骤(8.6);

(8.4)将指针变量p指向的结点线程的回溯位置设置为p1;

(8.5)将指针变量p指向的结点线程的局部锁lock设置为false,转入步骤(9);

(8.6)将指针变量p1指向的结点线程的局部锁lock设置为false,转入步骤(9);

(9)结束步骤:当前线程的任务完成,返回同步请求的执行结果。

总体而言,通过本发明所构思的以上技术方案与现有技术比,能够取得下列有益效果:

(1)提高了共享资源的访问效率。在combiner线程执行完一定数量的同步请求后,combiner线程将从当前的位置开始,沿着线程的同步请求的链表向前遍历,寻找绑定在宿主NUMA节点中的线程作为新的combiner线程,并且告知该combiner线程下一次执行任务时的回溯位置,因而在共享资源的访问比较分散的情况下,使得数据尽量保持在宿主NUMA节点内, 从而量减少了远程内存引用以及多个NUMA节点内的多个缓存因数据一致性而带来的通信消耗。

(2)公平性。与现有的方法相比,本发明保证线程访问共享资源的全局FIFO(先入先出)性质。

(3)统一的接口。本发明将同步访问的机制进行封装,对外提供统一的接口,应用时只需链接基于本发明的动态链接库即可。

附图说明

图1为本发明的整体示意图。

图2为本发明用于在多核多线程环境下NUMA感知的同步方法的流程图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

图1所示为本发明用于多核多线程环境下的NUMA感知的同步方法的整体示意图。如图1所示,圆形的结点代表线程的同步请求,每个线程一个,黑白颜色表示线程来自不同的NUMA节点,同一个颜色意味着来自于同一个NUMA节点。图中字母a、b、c表示combiner线程执行完最后一个同步请求后停留的位置的3种可能的情况。第一种情况a:如果下一个需要被服务的同步请求结点来自于宿主NUMA节点,则将拥有该结点的线程作为新的combiner线程;第二种情况b:如果下一个结点为尾结点,则将该尾结点的参数locked设置为false,然后返回;第三种情况c:如果下一个需要被服务的同步请求结点来自于非宿主NUMA节点,则从该结点开始,沿着指向下一个结点的指针遍历。如果遍历的过程中遇到的同步请求结点来自于宿主NUMA节点内,则将拥有该结点的线程作为新的combiner线程,并且设置该combiner线程的回溯位置为遍历开始位置的那个结点;否则直接指定遍历开始位置的那个结点的线程为新的combiner线程。

图2所示为本发明用于多核多线程环境下的NUMA感知的同步方法的流程图,包括以下步骤:

(1)线程设置自己的同步请求结点的相关参数,将线程的NUMA节点 编号设置为空,线程的下一结点指针next设置为空,局部锁状态变量lock设置为true,同步请求执行标记completed设置为false;然后获取同步请求链表尾指针PT(该尾指针是由用户在使用本方法前设置的,它指向一个同步请求结点,该结点的lock设置为false,completed设置为false);

(2)插入同步请求结点,包括如下子步骤:

(2.1)使用原子操作SWAP将同步请求链表尾指针PT指向本线程当前的同步请求结点,SWAP返回操作前同步请求链表尾指针并将其赋值给指针变量current;

(2.2)计算出current所指向的结点所在的NUMA节点的编号:根据当前线程的线程号计算出current所指向的结点所在NUMA节点的节点号,其中,线程号是线程创建的时候为其设置的一个编号,线程在运行的时候被绑定在特定的核上,所以线程编号与核的编号有个对应关系,进而与NUMA节点编号也有关系。具体怎么绑定,这是根据不同的处理器厂商而确定的,因为不同的处理器厂商制造的处理器之间的连接方式不一样。不同的处理器架构有不同的绑定策略,根据该绑定策略可以计算出这个核所在的NUMA节点号。

(2.3)将指针变量current所指向结点的next指针指向刚刚插入的那个结点;

(3)线程在指针变量current指向的结点的局部锁上面自旋,同时判别当前等待访问临界区的线程数目是否大于计算机内的处理器核的数目,是则调用linux库函数sched_yield(),暂时放弃处理器的使用权,该库函数执行返回后继续自旋;否则线程就继续自旋;一旦局部锁被释放则自旋结束进入步骤(4);

(4)判别当前线程的同步请求是否已经被执行,是则转入步骤(9),否则进入步骤(5);

(5)判别标志宿主NUMA节点的编号是否被设置过,是则不作处理, 转步骤(6);否则设置其值为当前线程所在的NUMA节点的编号,转步骤(6);

(6)设置回溯位置步骤:设置指针变量p来存储指针变量current值;

判别指针变量p指向的结点线程的回溯位置是否非空,是则将指针变量p指向所述回溯位置,然后将指针变量p原来的回溯位置设置为空,进入步骤(7);否则不作处理,转步骤(7);

(7)遍历并服务同步请求链表,此时将当前线程作为combiner线程,包括如下子步骤:

(7.1)从指针变量p所指向的结点开始遍历同步请求链表,如果同步请求链表中指针变量p指向的结点的指针next非空,且标志当前线程所服务的同步请求的数量的局部计数器的值未超过计数上限值M,则进入(7.2);否则转步骤(8);M为当前线程数目的3倍;

(7.2)根据指针变量p指向的结点的next,将next值用指针变量tmp_next暂存;

(7.3)将局部计数器的值加1;

(7.4)为指针变量p指向的结点线程执行其同步请求,将该线程同步请求执行标记completed设置为true;

(7.5)将指针变量p指向的结点线程的局部锁lock设置为false,释放该局部锁lock;

(7.6)将指针变量tmp_next赋给指针变量p,转向步骤(7.1);

(8)选择下一个combiner线程,包括以下子步骤:

(8.1)判别指针变量p指向结点是否为尾结点,是则将尾结点的lock设置为false,然后转向步骤(9);否转子步骤(8.2);

(8.2)判别指针变量p指向的结点的NUMA节点编号是否为宿主NUMA编号,是则将指针变量p指向的结点线程的lock设置为false,此时该线程作为combiner线程,然后进入步骤(9);否则转子步骤(8.3);

(8.3)将指针变量p的值赋值给指针变量p1,从指针变量p指向的结 点开始,沿着其next指针向下遍历各个结点,判别是否找到某结点的NUMA节点编号为宿主NUMA节点编号,是则进入子步骤(8.4);否则转入子步骤(8.6);

(8.4)将指针变量p指向的结点线程的回溯位置设置为p1;

(8.5)将指针变量p指向的结点线程的局部锁lock设置为false,转入步骤(9);

(8.6)将指针变量p1指向的结点线程的局部锁lock设置为false,转入步骤(9);

(9)当前线程的任务完成,返回同步请求的执行结果。

实验结果表明,本发明提出的NUMA感知的同步方法,与现有的技术相比,在跨NUMA节点的情况下,在共享资源的访问模式比较分散的情况下,就是线程数目多于单个芯片内处理器核的数目的条件下,单位时间内本方法访问共享资源的吞吐量提高了38%。

本领域的技术人员容易理解,以上所述仅为本发明的较佳实施实例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号