首页> 中国专利> 一种关于模板库编程约定的检查方法

一种关于模板库编程约定的检查方法

摘要

本发明公开了一种关于模板库编程约定的检查方法,属于计算机并行程序设计技术领域。本发明首先将编程约定描述为状态,以及将状态的迁移描述为编程约定中对指定方法的调用;然后将状态实现为类,并在类中编写符合编程约定的方法来供编程人员调用,以保证当编程人员违反编程约定的时候让编译器会停止编译并给出相应提示;预测编程人员可能会出现哪些错误,并在相应的表示状态的类中添加方法,使得当编程人员违反编程约定时能给出相应的提示信息以帮助编程人员检查并修改错误。本发明能够有效提高编程人员编写并行程序的效率。

著录项

  • 公开/公告号CN105022653A

    专利类型发明专利

  • 公开/公告日2015-11-04

    原文格式PDF

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

    申请/专利号CN201510381789.4

  • 申请日2015-07-03

  • 分类号G06F9/45;G06F11/36;

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

  • 代理人廖盈春

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

  • 入库时间 2023-12-18 11:38:13

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2017-12-12

    授权

    授权

  • 2015-12-02

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

    实质审查的生效

  • 2015-11-04

    公开

    公开

说明书

技术领域

本发明属于计算机并行程序设计技术领域,更具体地,涉及一种关于 模板库编程约定的检查方法。

背景技术

随着计算机CPU不断向着多核化发展,追求高性能单核处理器时代已 经结束,人们再也无法像以前一样只用等待芯片制造商推出新的处理器就 能获得程序性能的提升,只能通过并行的方式来提升串行应用程序的性能, 程序员开始走向并行编程之路。

传统的并行编程模型(例如MPI和较早版本的OpenMP)只能面向专家 级、资深程序员或者只能适应规则的应用。多核时代需要的是面向更广阔 应用领域的、易编程、高产能的并行编程工具。近几年涌现出许多新型并 行编程模型,其中,任务并行编程模型因为具有适用面广、编程方便、多 核使用率高的优点而成为多核平台上首选的并行编程模型。任务并行编程 模型把任务作为并行的基本单位,提供任务划分和同步的编程接口,把任 务划分和同步工作交给程序员完成,用户可以把应用程序划分出大量细粒 度任务。然而,具体到每个任务到底是并行执行还是串行执行、在哪个物 理核上执行以及如何实现任务之间的同步则由运行时系统完成。任务并行 编程模型提倡嵌套的递归任务,并引入以任务窃取为核心的用户级线程调 度,实现程序的高性能和动态的负载平衡。

任务并行编程模型包括任务并行模板库,其优点在于不需要改变开发 环境,即不需要新的编译器和集成开发环境;缺点是当用库的应用程序编 程接口(Application Programming Interface,API)表达任务并行时, 代码很难理解和修改,特别是当任务并行模板库使用C++语言实现(例如 Intel提出的TBB)时,若编程人员无意中违反库的使用约定,由于模板一 般嵌套较深,当程序发生错误时产生的错误信息将极为冗杂与晦涩,寻找 与排除错误对于编程人员而言无疑成为了一种较大的负担。若在程序运行 时加入大量的检查,会对程序的性能带来损害。因此,如何使任务并行模 板库在编程人员出现失误时给出的出错提示更加友好并且不影响程序性能, 仍是并行程序设计中亟需解决的问题。

发明内容

针对现有技术的以上缺陷或改进需求,本发明提供一种关于模板库编 程约定的检查方法,通过将编程约定进行抽象,可有效解决现有C++任务并 行模板库难于定位程序中不符合编程约定的代码的问题。

本发明提供一种关于模板库编程约定的检查方法,包括以下步骤:

步骤1将编程约定描述为D状态、W状态、C状态和T状态,分别表示 构造para对象成功、operator[]方法调用成功,operator()方法调用成功 和then方法调用成功,并将状态的迁移描述为编程约定中指定方法的调用;

步骤2将各状态实现为类,并在类中编写符合编程约定的方法来供编 程人员调用;

步骤3预测编程人员可能会出现的错误,并在相应的表示状态的类中 添加方法,使得当编程人员违反所述编程约定时给出相应的提示信息,以 帮助编程人员检查并修改错误,包括以下子步骤:

(3-1)初始时,当前状态为D状态,编程人员构造出用于容纳并行任 务的para对象,并为所述para对象的实例化提供一个表示其返回值类型 的模板参数,所述para对象中重载了operator[]方法,用于表示不同任务 间的依赖关系,若正确调用所述operator[]方法,则其将返回一个 para_accepted_wait对象,当前状态进入W状态,执行步骤(3-2),否则 引发static_assert断言为假,此时编译终止并输出错误发生所在的行数 来帮助编程人员修正错误;所述para对象还重载了operator()方法,用于 给para对象指定要执行的任务,若正确调用operator()方法,则其将返回 一个para_accepted_call对象,当前状态进入C状态,执行步骤(3-3), 否则引发static_assert断言为假,此时编译终止并输出错误发生所在的 行数帮助编程人员修正错误;

(3-2)当前状态处于W状态,表示程序中有一个符合编程约定的类型 为para_accepted_wait的依赖关系对象,并且该对象包含从之前的状态继 承而来的返回值类型,所述Para_accepted_wait对象中重载了operator() 方法并定义了then方法,所述then方法不执行任何代码,仅用于引发静 态断言错误;

(3-3)当前状态程序处于C状态,表示程序中有一个符合编程约定的 类型为para_accpted_call的可执行对象,并且该对象包含从之前的状态 继承而来的返回值类型,且该对象只能调用其then方法;

(3-4)当前状态处于T状态,表明程序中不存在违反编程约定的代码, 程序可以顺利通过编译。

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

本发明通过将编程约定转换为状态迁移图,强制编程人员遵守相关规 定,并在编程人员违反相关规定时给出友好的提示以帮助编程人员快速定 位并排除错误;所有的检查都发生在程序的编译期,因此对程序性能不构 成损失;本发明具有可扩展性,预测出编程人员可能会犯的所有错误的类 型是不可能的,但是在使用过程中可以针对新发现的错误类型向转台迁移 图中添加新的状态或方法,过程较为简易。

附图说明

图1为本发明关于模板库编程约定的检查方法的流程图;

图2为本发明将编程约定转化为状态迁移图的示意图;

图3为本发明捕获编程约定违例的流程图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图 及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体 实施例仅仅用以解释本发明,并不用于限定本发明。此外,下面所描述的 本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可 以相互组合。

在本发明提供的C++任务并行模板库中,要求编程人员按如下方式使用 该库:使用para对象容纳一个可执行对象,可执行对象必须是函数或者重 载了operator()方法的类的实例。para是一个模板类,要求用户给出一个 模板类型参数用以表示可执行对象的返回值类型。para对象之间还可以用 &&或||运算符连接,以得到一个wait对象,其中,&&运算符表示必须等待 运算符两边的任务都完成之后才能执行后续的任务;||运算符表示待运算 符两边任一任务完成后就能执行后续任务。wait对象表示一个依赖表达式, 其他para对象可以借助经过重载的operator[]方法接受一个wait对象, 表示该para对象中容纳的可执行对象的执行依赖于该wait对象中所包含 的可执行对象的执行,wait对象仍然可以通过&&或||运算符与其他para或 wait对象的连接并返回wait类型的对象以表示更复杂的依赖表达式。若 para对象中的可执行对象依赖于其他任务,则para对象必须先调用 operator[]方法接受一个wait对象,然后再调用operator()方法接受该可 执行对象,且要求可执行对象的参数类型为void或者符合依赖表达式的返 回值的类型。若para对象不依赖任何其他任务的执行,则可直接调用 operator()方法传入可执行对象。在para对象调用operator()方法后,需 要调用then方法并传入一个可执行对象表示并行任务结束后要执行的附加 任务,要求传入的可执行对象的参数为void或者与para对象的模板类型 参数相同,当传送给then方法的可执行对象执行后,整个流程结束。

图1是本发明C++任务并行模板库编程约定检查方法的工作流程图,具 体包括以下步骤:

步骤1将编程约定描述为状态,在本发明实施例中描述了D、W、C、 T4个状态,分别表示构造para对象成功、operator[]方法调用成功, operator()方法调用成功、then方法调用成功,并将状态的迁移描述为编 程约定中指定方法的调用。

步骤2将各状态实现为类,并在类中编写符合编程约定的方法来供编 程人员调用,以保证当编程人员违反编程约定的时候,编译器会停止编译。 图2所示为本发明将编程约定转化为状态迁移图的示意图。如图2所示, 图中每个节点表示表示一个状态,该状态下只能以编程约定中规定的方式 调用有限的方法,图中每一条边表示允许调用的方法。图中的状态迁移过 程中包含D、W、C、T四个状态,其中D状态通过operator()边和operator[] 边分别与C状态和W状态相连,W状态通过operator()边与C状态相连,C 状态通过then边与T状态相连。

D状态发生在程序初始时,编程人员构造出用于容纳并行任务的para 对象,并且为该对象的实例化提供一个表示其返回值类型的模板参数。在D 状态中通过调用operator[]方法得到一个包含相应的返回值类型 para_accepted_wait对象,该对象表示一个任务间的依赖关系,此时进入 W状态。在D状态中通过调用operator()方法得到一个包含有与para对象 同样的返回值类型的para_accepted_call对象,该对象表示一个具有相应 返回值类型的可执行的任务,此时进入C状态。

W状态表示程序中有一个符合编程约定的类型为para_accepted_wait 的依赖关系对象,并且该对象包含从之前的状态继承而来的返回值类型。 在W状态中通过调用operator()方法得到一个与para_accepted_wait对象 相同的返回值类型的para_accepted_call对象,该对象表示一个具有相应 返回值类型的可执行的任务,此时进入C状态。

C状态表示程序中有一个符合编程约定的类型为para_accpted_call的 可执行对象,并且该对象包含从之前的状态继承而来的返回值类型。在C 状态中通过调用then方法来得到一个与继承而来的返回值类型相同类型的 值并返回给程序,此时进入T状态。

T状态表示程序中有若干可能有任务间依赖关系的任务得以并行执行, 并返回了程序所需的结果。

步骤3预测编程人员可能会出现哪些错误,并在相应的表示状态的类 中添加方法,使得当编程人员违反编程约定时能给出相应的提示信息以帮 助编程人员检查并修改错误,包括以下子步骤:

(3-1)当前状态处于初始D状态,编程人员已构造出para对象。编 程人员可能会犯的错误为:1、未调用operator()方法的情况下调用了then 方法。则在para类中加入then方法并在方法中引发static_assert失败 用以在编译时告知编程人员对para对象使用不当。2、调用operator()方 法时传入的可执行对象不符合要求,具体表现为可执行对象的返回值与 para对象所持有的返回值对象不同,则在para类加入对operator()方法 的重载,并用C++标准库提供的enable_if匹配不合法的情况并在方法中引 发static_assert失败用以在编译时告知编程人员对operator()方法调用 不当。3、调用operator[]方法是传入的并不是wait对象或para对象,则 在para类用加入对operator[]方法的重载,并用C++标准库提供的 enable_if匹配不合法的情况并在方法中引发static_assert失败用以在编 译时告知编程人员对operator[]方法调用不当;

(3-2)当前状态处于W状态,表示程序中存在一个para_accepted_wait 对象。编程人员可能会犯的错误为:1、未调用operator()方法的情况下调 用了then方法。则在para_accepted_wait类中加入then方法并在方法中 引发static_assert失败用以在编译时告知编程人员对 para_accepted_wait对象使用不当。2、调用operator()方法时传入的可 执行对象不符合要求,具体表现为可执行对象的返回值与para对象所持有 的返回值对象不同,则在para_accepted_wait类加入对operator()方法的 重载,并用C++标准库提供的enable_if匹配不合法的情况并在方法中引发 static_assert失败用以在编译时告知编程人员对operator()方法调用不 当;

(3-3)当前状态处于C状态,则表示程序中存在一个 para_accepted_call对象。编程人员可能会犯的错误为:1、调用then方 法时传入的可执行对象不符合要求,具体表现为可执行对象的参数类型与 para_accpted_call对象执行后所返回的值的类型不兼容,则在 para_accepted_call类加入对then方法的重载,并用C++标准库提供的 enable_if匹配不合法的情况并在方法中引发static_assert失败用以在编 译时告知编程人员对then方法调用不当;

(3-4)当前状态处于T状态,表示程序中不存在违反编程约定的代码, 程序可以顺利通过编译

图3所示为本发明捕获编程约定违例的流程图。如图3所示,本发明 步骤3捕获编程约定违例的工作流程具体包括以下子步骤:

(3-1)初始时,当前状态为D状态。编程人员构造出用于容纳并行任 务的para对象,并且为该对象的实例化提供一个表示其返回值类型的模板 参数。

para对象中重载了operator[]方法,用于表示不同任务间的依赖关系, operator[]方法接受的对象应该是一个para或者wait对象。同时,利用 C++标准库提供的enable_if元函数检查传递给operator[]方法的参数是否 符合编程约定。若正确调用operator[]方法,则其将返回一个 para_accepted_wait对象,当前状态进入W状态,执行步骤(3-2)。反之, 若编程人员没有正确调用operator[]方法,则引发static_assert断言为 假,此时编译终止并输出“You can only wait for a para<...>object or  a dependency expression while using operator[].”和错误发生所在的 行数来帮助编程人员修正错误。

para对象还重载了operator()方法,用于给para对象指定要执行的 任务,operator()方法接受一个可调用对象作为参数,并且要求此对象的 参数部分应当与构造para时编程人员提供给para的模板参数相同。同样 的,利用C++标准库提供的enable_if元函数检查传递给operator()方法 的参数是否符合编程约定。若编程人员正确调用operator()方法,则其将 返回一个para_accepted_call对象,当前状态进入C状态,执行步骤(3-3)。 反之,调用operator()方法会引发static_assert断言为假,此时编译终 止并输出“The function's return type in operator(...)doesn't match  para<...>”和错误发生所在的行数帮助编程人员修正错误。

由于编程人员可能无意中对空的para对象调用then方法,所以在para 对象中提供了一个then方法,但是这个方法不执行任何代码,仅用于引发 静态断言错误,此时编译终止并输出“You can only call*then*right  after calling operator(...),like this, para<>a;a([](){...}).then(...);”和错误发生所在行数帮助编程人员修 正错误;

(3-2)当前状态处于W状态,表示程序中有一个符合编程约定的类型 为para_accepted_wait的依赖关系对象,并且该对象包含从之前的状态继 承而来的返回值类型。Para_accepted_wait对象中重载了operator()方法 并定义了then方法,对这两个方法的行为描述同D状态中对这两个方法的 描述。若正确调用operator()方法,则其将返回一个para_accepted_call 对象,当前状态进入C状态,执行步骤(3-3)。由于编程人员可能无意中 会试图在para_accpted_wait对象上调用then方法,所以在 para_accepted_wait类中提供了一个then方法,但是这个方法不执行任何 代码,仅用于引发静态断言错误,此时编译终止并输出“You can only call *then*right after calling operator(...),like this, para<>a;a([](){...}).then(...);”和错误发生所在行数帮助编程人员修 正错误;

(3-3)当前状态程序处于C状态,表示程序中有一个符合编程约定的 类型为para_accpted_call的可执行对象,并且该对象包含从之前的状态 继承而来的返回值类型。该对象只能调用其then方法,then方法接受一个 可调用对象作为参数,并要求该可调用对象的参数的类型与 para_accepted_call对象继承而来的返回值类型相同。同时,利用C++标 准库提供的enable_if元函数检查传递给then方法的参数是否符合编程约 定。若正确调用,则返回可调用对象的返回值。反之,若不符合编程约定, 则调用then方法会引发static_assert断言为假。具体情况分为:

1、若作为参数的可调用对象的参数的类型与之前的para或者wait对 象的返回值的类型不同时,此时编译终止并输出“The parameter's type in  then's callback function doesn't match associated para<...>'s return  type”和错误发生所在的行数来帮助编程人员修正错误;

2、若传递给then方法的不是一个可调用对象,此时编译终止并输出 “*then*must take a callable object as parameter,like lambda, functor,or std::function”和错误发生所在的行数来帮助编程人员修正 错误。

由于编程人员可能无意中对para_accepted_call对象调用operator() 与operator[]方法,所以在para对象中提供了operator()与operator[] 方法的重载,但是这两个方法不执行任何代码,仅用于引发静态断言错误, 此时编译终止并分别输出“You cannot call operator()after operator()” 和“You can only call operator[]before calling calling operator(...), instead of after calling operator(...)!”以及错误发生所在行数帮助 编程人员修正错误。

(3-4)当前状态处于T状态,表明程序中不存在违反编程约定的代码, 程序可以顺利通过编译。

在本发明C++任务并行模板库编程约定检查方法中,所有的检查均在编 译期进行,并且能给出友好的错误信息并给出解决的相应提示,在不影响 程序运行时的效率的同时保证程序正确性。

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

去获取专利,查看全文>

相似文献

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

客服邮箱:kefu@zhangqiaokeyan.com

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

  • 服务号