2. 西安邮电大学 陕西省网络数据分析与智能处理重点实验室, 西安 710121
2. Shaanxi Key Laboratory of Network Data Analysis and Intelligent Processing, Xi'an University of Posts and Telecommunications, Xi'an 710121, China
开放科学(资源服务)标志码(OSID):
随着计算机硬件技术的更新迭代,多核处理器以及众核处理器[1]被广泛应用,越来越多的开发人员使用并发编程来提高程序的性能,提升了程序的运行速度、吞吐量和CPU利用率。然而,并发程序内部存在并发性和不确定性,这会导致并发程序出现死锁[2]、数据竞争[3]、原子性违背[4]、顺序违背[5]等难以检测和修复的问题。数据竞争往往是引发其他并发问题的根本原因,在所有的并发缺陷问题中占较大比例,也是目前研究最多的一类问题[2]。如何有效地构建多线程数据竞争检测模型、设计或改进数据竞争定位算法以及准确识别多线程程序中的安全故障,是多线程并发程序安全性质量保障亟待解决的问题,其影响到多核处理器在各个领域的普及与应用。
针对数据竞争检测问题,国内外已有较多研究成果。在动态检测方面,Djit+[6]基于发生序关系方法,使用向量时钟对数据竞争进行分析,同时还包括FastTrack[7]、LOFT[8]和基于锁集的检测工具Eraser[9]。在静态检测方面,常用的检测工具有RacerX[5]、LOCKSMITH[10]和RELAY[11]。此外,蔡彦等提出一种基于采样的数据竞争检测方法来降低检测的开销,并开发了检测工具AtexRace[12],孙家泽等提出一种基于随机森林的数据竞争指令级检测方法,并实现了AIRaceTest检测工具[13]。然而,这些检测方法中仍存在误报、漏报以及开销大等问题。
本文基于数据挖掘分类模型可高效处理大量数据的特点,提出一种以语句对特征作为样本集建立Adaboost[14]分类模型的方法,实现多线程程序数据竞争检测工具ADR。通过对被测程序进行动态插桩取样并对插桩[15]结果进行语句级转化提取语句对特征,以此构建数据竞争Adaboost检测模型。由于数据竞争最终都可以归结到2条线程交织[16],因此本文分析来自2条不同线程的语句对,以简化检测过程。
1 数据竞争语句级检测算法 1.1 传统数据竞争检测在对被测程序进行动态插桩取样时,需要取出指令的所在线程
针对传统数据竞争检测方法误报率高、检测精度低的问题,本文提出一种基于语句对特征的数据竞争检测方法。首先对样本程序集进行插桩,提取出语句对的数据竞争相关属性,然后根据得到的数据集进行模型训练,最后根据得到的分类模型对被测并发程序进行数据竞争检测。本文采用的是集成分类模型。集成分类模型由若干单个分类器组成,相较于单一分类器而言,模型精度会更高。集成分类算法里最常用的是Adaboost算法和随机森林算法,Adaboost相较于随机森林而言,其各个弱分类器之间存在迭代关系,模型分类准确率更高。因此,本文先采用Adaboost算法建立模型,再利用建立好的模型进行数据竞争检测。
本文方法的具体检测过程如下:
1)训练过程
(1)设样本并发程序
(2)剔除掉无对应原码的指令以及来自同一条语句的指令,每一条语句仅保留一条指令,将指令级的插桩转换成为语句级插桩。
(3)遍历所有的语句对,提取出语句对中的Pm、Po、Pv、Pl、Pr这5项数据竞争相关属性。
(4)提取特征Pm。语句对
(5)提取特征Po。取出语句
(6)提取特征Pv。假设线程总数一定,该值为常量MmaxThreads,每一个线程维护一个向量时钟,表示为
(7)提取特征
(8)提取特征
(9)模型训练。以
训练过程的算法描述如下:
输入 样本程序P1
输出 Adaboost模型
1.对样本程序P1进行动态插桩
2.将指令级插桩转化语句插桩,提取出语句对
3.foreach语句对(a,b)do:
4.
5.
6.
7.Pl= extract_Lockset(a,b)
8.
9.SampleSet=Combine(
2)检测过程
(1)提取被测并发线程
(2)利用训练好的Adaboost模型对提取得到的属性进行分析,得到检测检测结果
(3)如果
检测过程的算法描述如下:
输入 样本程序P2
输出 数据竞争检测结果result
1.对样本程序P2进行动态插桩
2.foreach语句对(a,b)do:
3.
4.
5.
6.
7.
8.if
9.result=“发生数据竞争”
10.else:
11.result=“未发生数据竞争”
2 Adaboost模型本文通过Intel Pin工具提取出语句对的特征样本数据,并根据该样本数据建立数据竞争Adaboost检测模型。本节具体描述Adaboost模型的建立过程。
2.1 数据采集数据采集过程如下:
1)输入多线程程序,使用Pin工具进行动态插桩取样。
2)记录程序中该语句所在的线程
3)记录程序中该语句所访问的内存地址
4)记录程序中该语句所对应的读写操作
5)记录程序中该语句的锁集
6)程序中该语句所在线程的向量时钟vector-clock。
7)记录程序中该语句所在的行号。
8)输出多线程程序语句的内存信息。
表 1列出了从多线程程序中随机抽取的5条案例语句信息,其中:
![]() |
下载CSV 表 1 多线程程序语句的内存信息 Table 1 Memory information of multithreading statement |
对表 1中的数据进行处理,提取出语句对的
![]() |
下载CSV 表 2 语句对数据数值化特征表 Table 2 Eigenvalue table of statement pair |
Adaboost[14]算法的设计思想主要是针对同一训练集将其训练成不同的分类器并构建在一起,最终形成一个更强的分类器。Adaboost算法流程如图 1所示。首先,每轮迭代中会在新训练集上产生一个新的学习器。然后,使用该学习器对所有样本进行预测,以评估每个样本的重要性。在每一次迭代时,会给每一个样本赋予一个权重,根据每一次预测的准确性进行动态调整,权重越高的样本会在下一次训练过程中占越大的比重,即准确性低的样本会被着重关注。
![]() |
Download:
|
图 1 Adaboost算法流程 Fig. 1 Procedure of Adaboost algorithm |
本文从Github[17]上选取5组多线程程序来训练Adaboost模型,取出的语句对经整合后总数为60 8631。对整理得到的数据进行预处理得到特征数据集TestUnity。在特征数据集TestUnity上进行Adaboost模型训练时,如果迭代次数
图 2显示了不同的决策树深度随着迭代次数的增加,其分类误差率的变化趋势,从中可以看出:当
![]() |
Download:
|
图 2 分类误差率与迭代次数的关系 Fig. 2 Relationship between classification error rate and iteration times |
本节通过一系列实验,验证所提方法的有效性。首先提出研究问题,然后介绍实验数据集,最后总结并分析实验结果。
3.1 研究问题针对本文所提出的多线程程序数据竞争检测工具ADR,从以下2个角度出发进行有效性验证。
1)与Eraser、Djit+等数据竞争检测工具相比,ADR检测准确率是否提升以及提升幅度。
2)与Eraser、Djit+等数据竞争检测工具相比,ADR的检测开销是否有所降低。
3.2 实验数据集由于目前没有任何机构或者研究人员发布数据竞争检测的精确数据集,因此本文选择Github[17]上的1组已知数据竞争结果的多线程并发程序进行插桩取样,将插桩结果作为建立Adaboost模型的训练集。
实验环境为Ubuntu19.04,处理器核心数为4,运行内存4 GB。选择的验证测试程序来源如下:
1)为验证Adaboost数据竞争检测模型的准确性,在Google Code的data-race-test[18]测试集中筛选出50组多线程并发程序组成一个测试程序TestCodes进行验证。
2)为验证Adaboost数据竞争检测模型的时间开销和内存开销,选择SPLASH-2基本套件[19]中的2组程序和Parsec基准程序3.1[20]中的3组程序来进行验证。具体如表 3所示。
![]() |
下载CSV 表 3 测试程序信息 Table 3 Information of test programs |
ADR体系结构如图 3所示,主要由模型构建模块和模型预测模块这2部分组成。本文首先利用样本程序的插桩结果训练得到Adaboost分类模型,然后利用建立好的分类器对待测程序进行数据竞争检测。
![]() |
Download:
|
图 3 ADR体系结构 Fig. 3 Architecture of ADR |
将ADR与Eraser、Djit+和Thread Sanitizer这3种种动态数据竞争检测工具进行对比实验。Eraser、Djit+和Thread Sanitizer分别使用的检测算法是Happen-Before、Lockset和Happen-Before+Lockset混合算法。
3.4 检测精度分析由于TestCodes程序由多个小程序示例组成,因此每个小程序示例可能存在零个或者多个数据竞争。本文定义以下3个指标来衡量检测精度:数据竞争检测的误报数FP,数据竞争检测的正确数TP,数据竞争检测的漏报数FN。4种检测工具对TestCodes程序的数据竞争检测结果如图 4所示,已知TestCodes中真实存在的数据竞争次数为80。
![]() |
Download:
|
图 4 不同数据竞争检测工具的检测精度 Fig. 4 Detection accuracy of different detection tools |
从TP值上来对比分析。ADR检测出到79次数据竞争,其检测准确度最高。Djit+容易受到线程调度的影响,所以漏报较多,Eraser与Thread Sanitizer由于是在原码级别进行的判断,会遗漏部分数据竞争。ADR采用的Adaboost分类模型是由若干个弱分类器组合而成,而且各个弱分类器之间存在迭代关系,使模型分类准确率更高。
从FP值上来对比分析。因为Eraser对很多确定性同步语句未进行处理,所以其误报数最多。Dijt+由于其使用的算法是Happen-Before,而ADR是在语句级上进行的实验,剔除了重复以及无对应原码的指令信息,因此降低了检测的误报数。
3.5 检测开销分析本文选取SPLASH-2基本套件中的radix、fft程序和Parsec基准程序3.1中的streamcluster、
![]() |
Download:
|
图 5 不同数据竞争检测工具的检测时间开销 Fig. 5 Comparison of detection runtime overhead of different detection tools |
![]() |
Download:
|
图 6 不同数据竞争检测工具的检测内存开销 Fig. 6 Comparison of detection memory overhead of different detection tools |
由图 5可以看出,Thread Sanitizer的检测时间开销最大,Djit+的时间开销仅次于Thread Sanitizer。这是因为Thread Sanitizer和Djit+使用的都是Happen-Before算法,当线程数量很多时,在各个线程之间状态切换非常麻烦,增加了时间的开销,且Thread Sanitizer还需要判断锁集的状态,所以时间开销最大。ADR通过高效处理大量数据建立检测模型加快了检测的速度,使检测的时间开销更小。综合检测数据可知,ADR检测的时间开销相比于其他检测方法降低约29.3%。
由图 6可以看出,Thread Sanitizer相比于其他的检测方法,其检测的内存开销最大。这是因为Thread Sanitizer保存了所有并发历史访问的锁集和向量时钟,而Djit+保留了所有的历史访问的向量时钟,因此,Thread Sanitizer产生的内存开销最大。ADR为语句级检测,在对待测程序进行插桩取样时,每一条语句仅保留一条指令,只需要记录各个线程在内存中的状态信息,剔除掉了无对应原码的指令,降低了内存开销。综合检测数据可知,ADR检测所产生的内存开销相比于其他检测方法降低约21.1%。
4 结束语本文提出一种基于语句对特征的数据竞争方法。利用插桩工具Pin对被测并发程序进行动态插桩,记录指令的相关内存信息。在此基础上,通过对指令信息进行过滤操作,将指令级插桩转换成语句级插桩,然后根据样本数据集建立数据竞争Adaboost模型,对被测程序进行数据竞争检测,并基于此模型实现数据竞争检测工具ADR。实验结果表明,该方法能够有效降低漏报率与误报率,同时检测过程不受线程调度的影响,可减少检测的时间开销和内存开销,提高检测效率。后续将在数据采集过程中引入采样策略,减少样本的数据量,从而进一步减少数据竞争检测的内存消耗,优化数据竞争的检测效率。此外,在基于语句对特征的数据竞争方法中融入更优的采样策略,也将是下一步的研究方向。
[1] |
朱怡安, 黄林林, 李联, 等. 多核平台下分区操作系统的安全关键任务调度方法[J]. 计算机工程, 2017, 43(12): 38-44. ZHU Y A, HUANG L L, LI L, et al. Safety-critical task scheduling method for partitioned operating system in multi-core platform[J]. Computer Engineering, 2017, 43(12): 38-44. (in Chinese) |
[2] |
黄理, 顾乃杰, 曹华雄. 基于Petri网的多线程程序死锁检测[J]. 计算机工程, 2016, 42(4): 1-6. HUANG L, GU N J, CAO H X. Deadlock detection in multi-threaded program based on Petri net[J]. Computer Engineering, 2016, 42(4): 1-6. (in Chinese) |
[3] |
NETZER R H B, MILLER B P. What are race conditions? Some issues and formalizations[J]. ACM Letters on Programming Languages and Systems, 1992, 1(1): 74-88. DOI:10.1145/130616.130623 |
[4] |
胡敏, 陈雨亭. 基于距离挖掘的多变量原子性违例检测[J]. 计算机工程, 2012, 38(13): 61-63, 74. HU M, CHEN Y T. Multi-variable atomicity violation detection based on distance mining[J]. Computer Engineering, 2012, 38(13): 61-63, 74. (in Chinese) |
[5] |
ENGLER D, ASHCRAFT K. RacerX: effective, static detection of race conditions and deadlocks[J]. ACM SIGOPS Operating Systems Review, 2003, 37(5): 237-252. DOI:10.1145/1165389.945468 |
[6] |
POZNIANSKY E, SCHUSTER A. MultiRace: efficient on-the-fly data race detection in multithreaded C++ programs[J]. Concurrency & Computation Practice & Experience, 2007, 19(3): 327-340. |
[7] |
FLANAGAN C, FREUNDS N, FastTrack: efficient and precise dynamic race detection[C]//Proceedings of the 30th ACM SIGPLAN Conference on Programming Language Design and Implementation. New York, USA: ACM Press, 2009: 121-133.
|
[8] |
CAI Y, CHAN W K. LOFT: redundant synchronization event removal for data race detection[C]//Proceedings of the 22nd International Symposium on Software Reliability Engineering. Washington D.C., USA: IEEE Press, 2011: 160-169.
|
[9] |
SAVAGE S, BURROWS M, NELSON G, et al. Eraser: a dynamic data race detector for multi-threaded programs[J]. ACM Transactions on Computer Systems, 1997, 31(5): 27-37. |
[10] |
PRATIKAKIS P, FOSTERJ S, HICKS M. Locksmith: context-sensitive correlation analysis for race detection[J]. ACM SIGPLAN Notices, 2006, 41(6): 320-331. DOI:10.1145/1133255.1134019 |
[11] |
VOUNG J W, JHALA R, LERNER S. RELAY: static race detection on millions of lines of code[C]//Proceedings of the 6th Joint Meeting of the European Software Engineering Conference and the ACM SIGSOFT Symposium on the Foundations of Software Engineering. New York, USA: ACM Press, 2007: 205-214.
|
[12] |
GUO Y, CAI Y, YANG Z J. AtexRace: across thread and execution sampling for in-house race detection[C]//Proceedings of Joint Meeting on Foundations of Software Engineering. New York, USA: ACM Press, 2017: 1-5.
|
[13] |
孙家泽, 阳伽伟, 杨子江. 多线程程序数据竞争随机森林指令级检测模型[J]. 清华大学学报(自然科学版), 2020, 60(10): 804-813. SUN J Z, YANG J W, YANG Z J. Random forest instruction level detection model for data race in multithreaded programs[J]. Journal of Tsinghua University(Science and Technology), 2020, 60(10): 804-813. (in Chinese) |
[14] |
曹莹, 苗启广, 刘家辰, 等. AdaBoost算法研究进展与展望[J]. 自动化学报, 2013, 39(6): 745-758. CAO Y, MIAO Q G, LIU J C. Research progress and prospect of AdaBoost algorithm[J]. Acta Automatica Sinica, 2013, 39(6): 745-758. (in Chinese) |
[15] |
SCHARDL T B, DENNISTON T, DOUCET D, et al. The CSI framework for compiler-inserted program instrumentation[J]. Performance Evaluation Review, 2019, 46(1): 100-102. DOI:10.1145/3292040.3219657 |
[16] |
操旺根. 并发程序数据竞争检测方法研究和分析[J]. 信息技术与信息化, 2019(12): 171-173. CAO W G. Research and analysis of concurrent program data competition detection method[J]. Information Technology and Informatization, 2019(12): 171-173. (in Chinese) |
[17] |
Data race benchmark[EB/OL]. [2020-10-10]. https://github.com/arnabd88.
|
[18] |
Data-race-test[EB/OL]. [2020-10-10]. https://code.google.com/p/data-race-test/.
|
[19] |
FARCHI E, NIR Y, UR S. Concurrent bug pattens and how to test them[C]//Proceedings of 2003 International Symposium on Parallel and Distributed Processing. Washington. D.C., USA: IEEE Press, 2003: 286-296.
|
[20] |
BIENIA C. Benchmarking modern multiprocessors[D]. Princeton, USA: Princeton University, 2011.
|