紀(jì)銘涵 齊林 張楊 董士程 李朝帥
摘 要:為了解決并行處理中同步阻塞會浪費系統(tǒng)資源和影響程序性能的問題,提出了一種基于CompletableFuture異步機(jī)制的自動重構(gòu)方法。首先,使用WALA靜態(tài)程序分析工具進(jìn)行訪問者模式分析、逃逸分析、別名分析以及數(shù)據(jù)流分析等靜態(tài)程序分析技術(shù),確定共享變量數(shù)據(jù)的操作方式;然后,基于CompletableFuture機(jī)制設(shè)置4種異步重構(gòu)模式;最后,根據(jù)不同模式實現(xiàn)異步機(jī)制的自動重構(gòu)?;诖朔椒?,在Eclipse平臺下開發(fā)了自動重構(gòu)工具AsynRef,并對HSQLDB,Jenkins,JGroups和SPECjbb2005等4個大型實際應(yīng)用程序進(jìn)行自動重構(gòu),從重構(gòu)個數(shù)、改變的代碼行數(shù)、準(zhǔn)確性和重構(gòu)后程序性能等方面對AsynRef進(jìn)行評估,對4個程序所包含的919個同步方法共完成387個異步機(jī)制轉(zhuǎn)換。結(jié)果顯示,使用AsynRef進(jìn)行異步機(jī)制重構(gòu)后,程序執(zhí)行性能有8%到39%的不同程度的提升。AsynRef可以有效完成代碼異步化自動重構(gòu),與傳統(tǒng)手動重構(gòu)相比,有效提升了異步化的重構(gòu)效率。
關(guān)鍵詞:并行處理;同步機(jī)制;異步機(jī)制;靜態(tài)程序分析;自動重構(gòu)
中圖分類號:TP311?? 文獻(xiàn)標(biāo)識碼:A
doi:10.7535/hbkd.2021yx05008
收稿日期:2021-06-15;修回日期:2021-09-22;責(zé)任編輯:王淑霞
基金項目:國家自然科學(xué)基金(61440012);河北省自然科學(xué)基金(18960106D);河北省高等學(xué)??茖W(xué)研究計劃重點項目(ZD2019093)
第一作者簡介:紀(jì)銘涵(1997—),女,河北邢臺人,碩士研究生,主要從事并發(fā)處理、軟件自動重構(gòu)方面的研究。
通訊作者:張 楊副教授。E-mail:zhangyang@hebust.edu.cn
An automated refactoring approach for asynchronous mechanism
JI Minghan,QI Lin,ZHANG Yang,DONG Shicheng,LI Chaoshuai
(School of Information Science and Engineering,Hebei University of Science and Technology,Shijiazhuang,Hebei,050018,China)
Abstract:As synchronous blocking wastes system resources and affects program performance in concurrent processing,an automatic refactoring approach based on the asynchronous mechanism of CompletableFuture was proposed.Firstly,several static analyses by Wala static program analysis tool,such as visitor pattern analysis,alias analysis,and data flow analysis were used in this approach,so that the operation mode of shared variable data was determined.Then four asynchronous refactoring modes were set based on the asynchronous mechanism of CompletableFuture.Finally,the code was refactored according to different modes.An automatic tool AsynRef was implemented by Eclipse and four large-scale practical applications such as HSQLDB,Jenkins,JGroups,and SPECjbb2005 were automatically refactored by AsynRef.AsynRef was evaluated via the number of refactored locks,changed lines of code,accuracy,program performance after refactoring.Among the 919 synchronous methods contained in the four programs,387 asynchronous mechanism conversions were completed.After Asynref was used for asynchronous mechanism refactoring,the program execution performance was improved by 8% to 39%.AsynRef can refactor for aynchronized mechanism effectively.Compared to manual refactoring,the refactoring efficiency is improved significantly.
Keywords:
concurrent processing;synchronization mechanism;asynchronous mechanism;static program analysis;automatic refactoring
隨著并發(fā)程序設(shè)計方法越來越多地被應(yīng)用于多線程程序開發(fā),為了保證程序的正確性,開發(fā)人員通過使用同步機(jī)制的方法進(jìn)行控制,確保了程序正確穩(wěn)健地運行。然而,由于存在不必要的同步控制,使用粗粒度的同步機(jī)制會使得開銷更大,從而導(dǎo)致執(zhí)行效率降低。在Java語言中,同步鎖簡單易用,在并發(fā)程序開發(fā)中得到了廣泛使用,但由于在使用同步鎖修飾整個方法體時會造成粗粒度同步保護(hù)的問題,使得程序性能無法得到保證。
使用多線程實現(xiàn)程序并行化是并發(fā)程序編程中的主要方式,但是對于臨界區(qū)的操作與訪問會引入數(shù)據(jù)競爭等并發(fā)問題。另外線程個數(shù)的設(shè)置也是有限制的,因此提高系統(tǒng)性能不能僅通過增加線程數(shù)來實現(xiàn),使用同步機(jī)制進(jìn)行編程方式是阻塞式的,會造成系統(tǒng)資源的浪費。異步機(jī)制是達(dá)到程序并行執(zhí)行的另一種方式,所謂異步就是通過將當(dāng)前任務(wù)線程與主應(yīng)用程序線程分開,達(dá)到獨立運行的效果。使用異步機(jī)制可以有效避免同步機(jī)制的阻塞影響,進(jìn)一步提高程序性能。越來越多的研究著眼于并發(fā)程序中的同步機(jī)制與異步機(jī)制,一些研究使用自動重構(gòu)工具幫助程序員在多種鎖機(jī)制之間進(jìn)行轉(zhuǎn)換,如針對重入鎖以及讀寫鎖提出了一種自動重構(gòu)算法[1],或者面向可定制鎖[2]和郵戳鎖[3]的自動重構(gòu)方法,以及在進(jìn)行優(yōu)化同步瓶頸的研究中提出的一種鎖分解方式[4]。但大多數(shù)研究還是僅針對同步機(jī)制,缺少對同步機(jī)制與異步機(jī)制兩者間關(guān)系以及2種機(jī)制之間相互轉(zhuǎn)換的研究,雖然人們已經(jīng)對并發(fā)程序中同步機(jī)制有了較深的探索,但并沒有考慮到異步機(jī)制在并發(fā)編程中的作用。
異步機(jī)制已經(jīng)被應(yīng)用到物聯(lián)網(wǎng)[5-7]、 WEB應(yīng)用[8-12]、移動端開發(fā)[13-15]和代碼重構(gòu)[16-19]等多個領(lǐng)域。李夏君 [5]對使用異步編程的程序進(jìn)行分析,結(jié)果表明使用異步編程有效提高了云平臺的執(zhí)行速度,并且使用異步編程的方式更加簡單。RAVINDRANATH等[6]提出了一組程序分析技術(shù)檢測異步回調(diào)實例,并將這種帶有錯誤優(yōu)先協(xié)議的回調(diào)重構(gòu)為promises,提供異步回調(diào)的替代方案。目前,雖然許多學(xué)者已經(jīng)認(rèn)識到異步機(jī)制對并發(fā)程序開發(fā)的重要性,并且在實際應(yīng)用中廣泛使用了異步編程,但目前缺少對并發(fā)程序中異步機(jī)制自動重構(gòu)方法的研究。
針對并行處理中同步阻塞浪費系統(tǒng)資源和影響程序性能的問題,本文提出了一種異步機(jī)制的自動重構(gòu)方法,采用WALA[20]軟件分析工具中多種靜態(tài)程序分析方法,如訪問者模式分析、逃逸分析、別名分析、數(shù)據(jù)流分析等確定進(jìn)行異步重構(gòu)的代碼,然后獲得共享變量數(shù)據(jù)操作方式,最后基于CompletableFuture機(jī)制實現(xiàn)異步重構(gòu)?;诖朔椒?,在Eclipse平臺下設(shè)計了一個可以進(jìn)行異步機(jī)制自動重構(gòu)的插件工具AsynRef,以實現(xiàn)源碼級別的重構(gòu),幫助開發(fā)者完成代碼異步化的自動轉(zhuǎn)換。在實驗中,對4種大型實際應(yīng)用程序進(jìn)行自動重構(gòu),從重構(gòu)個數(shù)、改變的代碼行數(shù)、準(zhǔn)確性和重構(gòu)后程序性能等方面對AsynRef進(jìn)行評估。
1 同步機(jī)制與異步機(jī)制性能對比
在Java 1.5中提供了Callable和Future機(jī)制,使用這2種機(jī)制可以實現(xiàn)異步方式執(zhí)行程序,但在獲取程序執(zhí)行結(jié)果時仍需同步等待獲得,因此并不能實現(xiàn)真正意義上的異步。在Java 8中,為了實現(xiàn)真正意義上的異步執(zhí)行效果,提出了新的Future機(jī)制即CompletableFuture機(jī)制,不同于原有的Future機(jī)制,CompletableFuture實現(xiàn)了在異步任務(wù)完成時,通過傳入的回調(diào)對象,調(diào)用回調(diào)方法并得到異步執(zhí)行的結(jié)果。
為了說明使用CompletableFuture機(jī)制進(jìn)行異步化程序的可行性,對文件讀取與寫入的耗時操作進(jìn)行了同步和異步2種執(zhí)行方式的性能對比,分別對50,100,300 M文件進(jìn)行100次讀取操作。該段測試程序選自openjdk-jdk 10項目,使用Files.write()和Files.readAllBytes()方法對文件進(jìn)行讀寫,通過對這2種方法進(jìn)行異步方式改寫,得到2種執(zhí)行方式的時間對比。圖1是分別使用同步機(jī)制和異步機(jī)制對3種不同大小文件進(jìn)行寫操作的執(zhí)行時間對比圖,3種不同大小文件使用異步方式的執(zhí)行時間均少于同步方式的執(zhí)行時間,并且隨著文件的增大,異步方式的優(yōu)勢更加明顯。圖2是分別使用同步機(jī)制和異步機(jī)制對100 M文件進(jìn)行讀操作與寫操作的執(zhí)行時間對比圖,無論是對于讀操作還是寫操作,異步方式的執(zhí)行時間更短。
對比上述文件的讀取程序,通過異步機(jī)制改進(jìn)后程序的執(zhí)行時間較同步方式有所縮短,說明在某些情況下異步機(jī)制執(zhí)行程序提高了程序的性能。
2 異步重構(gòu)模式
2.1 重構(gòu)框架
異步重構(gòu)首先通過靜態(tài)程序分析方法對并發(fā)程序進(jìn)行分析,然后對可以進(jìn)行重構(gòu)的代碼通過異步模式進(jìn)行判斷,最后進(jìn)行相應(yīng)的異步模式重構(gòu)。對于一個源程序代碼,先提取對應(yīng)的抽象語法樹,再使用訪問者模式對抽象語法樹中各個節(jié)點進(jìn)行遍歷,然后使用多種程序靜態(tài)分析方法進(jìn)行程序分析。其中逃逸分析用來分析共享變量動態(tài)作用域,別名分析用來解決鎖集中的別名問題,數(shù)據(jù)流分析用來分析共享變量依賴關(guān)系。異步模式判斷模塊根據(jù)數(shù)據(jù)流分析結(jié)果進(jìn)行4種異步重構(gòu)模式的判斷,并選擇相應(yīng)的模式進(jìn)行重構(gòu)。重構(gòu)過程主要是對源程序的抽象語法樹進(jìn)行節(jié)點添加、修改等操作,最終將原有的程序執(zhí)行過程轉(zhuǎn)換為異步執(zhí)行的過程。面向異步機(jī)制的重構(gòu)框架如圖3所示。
2.2 程序靜態(tài)分析
使用WALA工具對程序進(jìn)行相應(yīng)的靜態(tài)程序分析。首先,通過訪問者模式遍歷程序中的所有方法,通過WALA分析獲得所有變量的訪問指令,遍歷函數(shù)調(diào)用圖每個節(jié)點,得到每個節(jié)點下的字段訪問指令;其次,使用逃逸分析確定可以進(jìn)行異步轉(zhuǎn)換的同步方法中的共享變量,利用別名分析去除別名現(xiàn)象對重構(gòu)的影響;最后,對共享變量進(jìn)行數(shù)據(jù)流分析,根據(jù)分析結(jié)果對異步重構(gòu)模式進(jìn)行判斷。
2.2.1 逃逸分析
雖然使用同步機(jī)制可以保證共享數(shù)據(jù)的準(zhǔn)確性,但由于粗粒度的同步保護(hù)開銷很大,在并發(fā)程序開發(fā)過程中存在不必要的同步操作,導(dǎo)致程序的執(zhí)行效率降低,可通過使用逃逸分析方法進(jìn)行鎖消除達(dá)到同步優(yōu)化的目的[21]。在進(jìn)行異步機(jī)制的自動重構(gòu)之前,通過逃逸分析確定當(dāng)前共享變量的使用范圍,保證當(dāng)前共享變量指針的生命周期只在當(dāng)前線程。
使用WALA收集到所有變量訪問操作后,收集所有共享變量accessField訪問存入集合VASet中進(jìn)行逃逸分析。通過收集類中可能存在逃逸現(xiàn)象的字段,定義escapeFields并存入收集到的所有字段,
定義逃逸訪問操作集合escapeSet,判斷訪問操作的訪問字段是否在escapeFields中。利用WALA中mayEscape方法對集合escapeSet進(jìn)行分析,確定是否發(fā)生逃逸。使用逃逸分析方法分析共享變量的使用范圍,對程序進(jìn)行鎖消除,對于不發(fā)生逃逸的共享變量進(jìn)行異步機(jī)制的轉(zhuǎn)換,具體分析過程如圖4所示。
2.2.2 別名分析
通過逃逸分析確定可以進(jìn)行異步機(jī)制轉(zhuǎn)換的方法,同時在進(jìn)行異步代碼重構(gòu)前,需要對共享變量鎖監(jiān)視器對象是否存在別名進(jìn)行分析。別名分析就是對共享變量進(jìn)行指針分析,當(dāng)同一個內(nèi)存地址被多個共享變量指向時即產(chǎn)生別名,通過別名分析減少由于別名而造成的對分析結(jié)果的影響[22]。使用別名分析可以有效避免進(jìn)行異步重構(gòu)時,由于共享變量產(chǎn)生別名問題而造成代碼重構(gòu)錯誤的問題。
在別名分析中,設(shè)置MonitorSet為監(jiān)視器集合,其中monitor_i為監(jiān)視器對象,監(jiān)視器monitor_i的指向集為PoniterSet_i。若2個監(jiān)視器對象的指向集交集不空,則說明2個監(jiān)視器互為別名,并將其存入別名集aliasSet中,對于沒有產(chǎn)生別名問題的鎖監(jiān)視器對象再重構(gòu)進(jìn)行實例化,具體分析過程如圖5所示。
2.2.3 數(shù)據(jù)流分析
數(shù)據(jù)流分析通過對程序中語義信息進(jìn)行分析,得到程序中數(shù)據(jù)的變化結(jié)果[23]。在進(jìn)行異步重構(gòu)時,對共享變量進(jìn)行數(shù)據(jù)流分析,確定異步重構(gòu)的模式。使用控制流圖CFG生成程序數(shù)據(jù)流圖DFG,對圖中各個節(jié)點進(jìn)行遍歷,通過對共享變量進(jìn)行數(shù)據(jù)流分析,可以確定對共享變量的操作是單一方法或是多個方法,以及多個方法間是否有依賴關(guān)系。對當(dāng)前的共享變量進(jìn)行數(shù)據(jù)流分析,若只涉及一個方法則以字符T存入數(shù)據(jù)操作序列S中,反之以字符F存入數(shù)據(jù)操作序列S中,具體分析過程如圖6所示。
2.3 基于CompletableFuture的異步模式
根據(jù)上述靜態(tài)分析方法,每個節(jié)點返回的數(shù)據(jù)操作結(jié)果可以將異步執(zhí)行代碼分成單個異步執(zhí)行任務(wù)和多個異步執(zhí)行任務(wù)2類,使用CompletableFuture異步機(jī)制給出4種異步代碼執(zhí)行的實現(xiàn)模式。
1)模式1 該模式主要針對單個異步執(zhí)行任務(wù),并且這個任務(wù)沒有返回值,通過使用Completable-Future類中提供的靜態(tài)方法runAsync()完成對異步任務(wù)的執(zhí)行。
2)模式2 該模式主要針對單個異步執(zhí)行任務(wù),并且這個任務(wù)有返回值,通過使用CompletableFuture類中提供的靜態(tài)方法supplyAsync()完成對異步任務(wù)的執(zhí)行。
3)模式3 該模式主要針對多個異步執(zhí)行任務(wù),當(dāng)調(diào)用方CompletableFuture的計算完成時,通過使用方法whenComplete()執(zhí)行下一個異步任務(wù)。
4)模式4 該模式主要針對多個異步執(zhí)行任務(wù),并且多個任務(wù)間是以串行方式執(zhí)行,即前一個有返回值的異步任務(wù)執(zhí)行結(jié)束后,返回值作為下一個任務(wù)的參數(shù)。
5)模式4a 前一個有返回值的異步任務(wù)執(zhí)行結(jié)束,返回值作為下一個有參數(shù)有返回值的異步任務(wù)參數(shù),通過使用方法thenApplyAysnc()完成對下一個異步任務(wù)的執(zhí)行。
6)模式4b 前一個有返回值的異步任務(wù)執(zhí)行結(jié)束,返回值作為下一個有參數(shù)無返回值的異步任務(wù)參數(shù),通過使用方法thenAcceptAysnc()完成對下一個異步任務(wù)的執(zhí)行。
2.4 重構(gòu)算法
在異步機(jī)制的自動重構(gòu)算法中,首先生成當(dāng)前代碼對應(yīng)的AST樹,然后對所有方法節(jié)點進(jìn)行遍歷,篩選出所有使用同步的方法,對方法中的共享變量進(jìn)行別名分析后,根據(jù)控制流分析使用相應(yīng)的異步重構(gòu)模式進(jìn)行代碼改寫,最后將重構(gòu)后的代碼重新添加到AST樹上完成重構(gòu)過程。
使用訪問者模式遍歷并發(fā)程序中同步方法,獲取每一個待重構(gòu)方法Bmethod的鎖監(jiān)視器對象,如果當(dāng)前方法是同步方法,則使用逃逸分析對共享變量是否逃逸進(jìn)行分析。具體重構(gòu)過程如圖7所示。對于不發(fā)生逃逸現(xiàn)象的共享變量,使用別名分析得到可以進(jìn)行重構(gòu)的同步方法鎖集合(行3)。接下來利用數(shù)據(jù)流分析共享變量,從而獲得異步重構(gòu)模式正則匹配字符串str(行4),進(jìn)行同步機(jī)制消除(行6)。在異步模式判斷過程中,在一個同步方法中,根據(jù)匹配序列對應(yīng)的共享變量順序,選擇對應(yīng)的異步重構(gòu)模式進(jìn)行代碼重構(gòu)。若當(dāng)前方法有返回值,并且當(dāng)前共享變量異步重構(gòu)模式匹配字符串為T時,則使用異步模式2進(jìn)行重構(gòu)(行18—19);若當(dāng)前方法有返回值,并且當(dāng)前共享變量異步重構(gòu)模式匹配字符串為F時,則使用異步模式4a進(jìn)行重構(gòu)(行20—21);若當(dāng)前方法沒有返回值,并且當(dāng)前共享變量異步重構(gòu)模式匹配字符串為T時,則使用異步模式1進(jìn)行重構(gòu)(行9—10);若當(dāng)前方法沒有返回值,并且當(dāng)前共享變量異步重構(gòu)模式匹配字符串為F時,若共享變量間有依賴關(guān)系,即前一個有返回值的異步任務(wù)執(zhí)行結(jié)束,其返回值需要作為下一個異步任務(wù)的參數(shù),此時則使用異步模式4b進(jìn)行重構(gòu)(行14),如果沒有依賴關(guān)系則使用異步模式3進(jìn)行重構(gòu)(行13)。根據(jù)不同的異步模式進(jìn)行代碼重構(gòu)改寫后,最后返回重構(gòu)后的異步方法Amethod,并更新原代碼的AST樹完成重構(gòu)。
2.5 重構(gòu)工具實現(xiàn)
針對異步機(jī)制的自動重構(gòu),開發(fā)了重構(gòu)工具AsynRef。該工具利用Eclipse平臺進(jìn)行開發(fā),最終以插件形式實現(xiàn)。通過對重構(gòu)工具中的基礎(chǔ)類進(jìn)行擴(kuò)展,實現(xiàn)相關(guān)異步模式重構(gòu)邏輯,得到異步機(jī)制自動重構(gòu)工具,重構(gòu)界面如圖8所示。
3 實驗評估
3.1 實驗配置
所有實驗在惠普Z240工作站上完成。CPU為Intel Core i7-7700 3.60 GHz,有4個處理核,同時支持8線程運行,內(nèi)存為8 GB,使用Windows 10操作系統(tǒng),開發(fā)環(huán)境為Eclipse 4.11,JDK版本為1.8.0_211,程序分析工具WALA的版本為1.52。
3.2 測試程序
使用HSQLDB,Jenkins,JGroups,SPECjbb2005等4個真實程序?qū)synRef進(jìn)行有效性和適用性驗證。4種真實程序分別取自不同的應(yīng)用領(lǐng)域,所含代碼行數(shù)等也有較大差別。其中HSQLDB是數(shù)據(jù)庫程序,Jenkins是服務(wù)器程序,JGroups是群組通訊工具,SPECjbb2005是服務(wù)器測試程序。4個程序及配置如表1所示。
3.3 結(jié)果及分析
在工具驗證階段,對4個真實程序進(jìn)行了自動重構(gòu),并由多個指標(biāo)給出驗證結(jié)果。
1)異步重構(gòu)個數(shù)
首先,選取HSQLDB,Jenkins,JGroups,SPECjbb2005等實際應(yīng)用程序?qū)μ岢龅姆椒ê凸ぞ哌M(jìn)行評估。從實驗結(jié)果可以看出,雖然源程序中有很多使用鎖機(jī)制的方法,但由于程序執(zhí)行本身不能進(jìn)行異步化處理,相較于不同鎖機(jī)制間的重構(gòu)轉(zhuǎn)換,異步轉(zhuǎn)換的個數(shù)會較少。4種異步模式重構(gòu)的程序個數(shù)如表2所示。
2)重構(gòu)前后改變的代碼行數(shù)
使用SLOCCount工具對重構(gòu)前后程序的代碼行數(shù)進(jìn)行統(tǒng)計,可以較為直觀地看到自動重構(gòu)工具減少的工作量,更加直觀地反映自動重構(gòu)工具所帶來的優(yōu)勢。
選取的4個應(yīng)用程序共包含471 218行代碼,重構(gòu)過程增加了4 106行代碼,重構(gòu)后為475 324行代碼。由于使用異步方式進(jìn)行程序執(zhí)行需要引入較多的代碼,所以相較于源程序,雖然可以進(jìn)行異步重構(gòu)的個數(shù)不多,但是帶來的代碼行數(shù)的改變還是較大的。對于HSQLDB程序來說,異步重構(gòu)前后改變的代碼行數(shù)最多,達(dá)到2 160行;對于Jenkins,SPECjbb2005和JGroups測試程序,分別增加了1 010,207和729行。
3)重構(gòu)前后性能對比
對比重構(gòu)前后程序的各項運行指標(biāo),對使用異步機(jī)制后的程序進(jìn)行分析。在HSQLDB程序中提供了基準(zhǔn)測試程序,通過改變業(yè)務(wù)數(shù)等參數(shù)進(jìn)行測試。測試結(jié)果如圖9所示,其中橫坐標(biāo)為處理事務(wù)數(shù),分別給出了事務(wù)數(shù)為100 000到500 000的情況,縱坐標(biāo)為事務(wù)處理率??梢钥吹皆谔幚硎聞?wù)數(shù)為100 000的程序時,使用異步后的程序事務(wù)率要遠(yuǎn)遠(yuǎn)低于源程序的;在事務(wù)數(shù)為200 000時,異步后的程序事務(wù)率有了提升,但依舊低于源程序;在事務(wù)數(shù)為300 000時,兩者的事務(wù)率基本持平;事務(wù)數(shù)為400 000和500 000時原程序的事務(wù)率有了下降,但使用異步的程序事務(wù)率要高于源程序。使用異步的程序事務(wù)率值呈現(xiàn)上升趨勢,說明在處理少量事務(wù)的時候,使用異步機(jī)制并不能帶來性能的提升,但隨著事務(wù)數(shù)不斷提高,異步機(jī)制的優(yōu)勢逐漸顯現(xiàn),證明在處理更多數(shù)據(jù)的時候異步機(jī)制具有更好的程序性能。
對于Jenkins程序,選取2個單元測試程序?qū)synRef工具進(jìn)行測試,執(zhí)行時間結(jié)果如圖10所示。其中對于FunctionsTest程序進(jìn)行異步重構(gòu)后,程序的執(zhí)行時間沒有出現(xiàn)明顯變化,而使用異步機(jī)制運行之后,F(xiàn)ielPathTest程序運行時間減少了39%。
對于JGroups選取了4個測試程序進(jìn)行測試,運行結(jié)果如圖11所示,其中縱坐標(biāo)是群組間信息請求處理率。對于RoundTrip,RoundTripRpc,UnicastTest和UnicastTestRpc程序,在使用異步機(jī)制進(jìn)行執(zhí)行后,請求處理率都有所提升,分別提升了13.5%,12.8%,8%和17%。
圖12和圖13給出了SPECjbb2005程序在進(jìn)行異步重構(gòu)前后的執(zhí)行結(jié)果。圖12是隨著線程數(shù)的改變程序吞吐量變化的情況,由圖12可知,使用異步執(zhí)行程序的吞吐量一直低于源程序的吞吐量,說明使用異步機(jī)制并不一定都能提升程序性能。圖13給出了在不同線程數(shù)執(zhí)行下,程序運行時堆內(nèi)存占總內(nèi)存的比例,可以得知在10種不同的線程數(shù)執(zhí)行情況中,只有2種情況下的堆內(nèi)存使用比是重構(gòu)前程序高于重構(gòu)后程序的,大多數(shù)情況下還是采用異步之后的堆內(nèi)存使用比更高,而在執(zhí)行線程數(shù)為8時,重構(gòu)前程序的堆內(nèi)存使用比遠(yuǎn)遠(yuǎn)高于重構(gòu)后程序,說明使用異步機(jī)制執(zhí)行程序在不同情況下對程序的提升程度是不同的。
4)重構(gòu)的正確性驗證
并發(fā)程序異步化后,相應(yīng)的方法不再是同步執(zhí)行,導(dǎo)致程序的準(zhǔn)確性不足以得到保證,雖然在異步重構(gòu)模式中有針對寫操作進(jìn)行原子操作轉(zhuǎn)換,但還可能存在“ABA”的問題,需要對程序重構(gòu)前后進(jìn)行驗證。主要對如下2個方面進(jìn)行正確性驗證,一是通過手動檢測方式對每一處更改為異步執(zhí)行的代碼進(jìn)行語法檢測,保證程序在執(zhí)行前不存在錯誤;二是將白盒測試與黑盒測試相結(jié)合,利用設(shè)置斷點的方式檢測重構(gòu)后各個方法執(zhí)行過程中數(shù)據(jù)的準(zhǔn)確性,使用黑盒測試檢測功能代碼,重構(gòu)前后的輸出結(jié)果一致。
首先,對異步執(zhí)行的代碼進(jìn)行語法檢測,通過Eclipse編譯錯誤檢測以及手工檢查每一個測試程序中異步重構(gòu)的代碼,發(fā)現(xiàn)每一處都符合所提出的異步重構(gòu)模式,并且人工檢測代碼語義都符合重構(gòu)前的功能。其次,對重構(gòu)后程序代碼的數(shù)據(jù)正確性進(jìn)行檢測,通過采用白盒測試與黑盒測試相結(jié)合的方式,檢測到相同輸入數(shù)據(jù)時,異步重構(gòu)前后方法輸出結(jié)果一致,且在方法執(zhí)行過程中方法體內(nèi)部共享變量數(shù)據(jù)準(zhǔn)確。最終結(jié)果表明,并未發(fā)現(xiàn)錯誤,異步重構(gòu)后的程序可以正確運行。
4 結(jié) 語
針對并行處理中同步阻塞會浪費系統(tǒng)資源和影響程序性能的問題,提出了一種面向異步機(jī)制的自動重構(gòu)方法。該方法利用訪問者模式分析、逃逸分析、別名分析以及數(shù)據(jù)流分析等多種程序分析技術(shù),可以將同步代碼自動重構(gòu)為基于CompletableFuture機(jī)制的4種異步模式。在實驗中通過4個實際應(yīng)用程序驗證了該方法的有效性,利用重構(gòu)工具完成了287個同步方法、4 106行代碼的重構(gòu)過程,表明該工具可以完成異步機(jī)制的自動重構(gòu)。對比異步重構(gòu)前后的程序執(zhí)行時間等指標(biāo)發(fā)現(xiàn),使用異步機(jī)制可以有效提高并發(fā)程序的執(zhí)行效率。但是,由于異步機(jī)制本身的復(fù)雜性,本文仍存在不足,未來將研究更多的異步重構(gòu)模式以及適合異步機(jī)制執(zhí)行的應(yīng)用場景,使用更多的實際應(yīng)用程序?qū)χ貥?gòu)工具進(jìn)行評估驗證。
參考文獻(xiàn)/References:
[1] SCHFER M,DOLBY J,SRIDHARANM,et al.Correct refactoring of concurrent java code[C]//.ECOOP 2010-object-oriented Programming.Berlin:Springer-Verlag Berlin Heidelberg,2010:225-249.
[2] ZHANG Y,SHAO S,LIU H,et al.Refactoring java programs for customizable locks based on bytecode transformation[J].IEEE Access,2019,7:66292-66303.
[3] ZHANG Y,DONG S C,ZHANG X Y,et al.Automated refactoring for stampedlock[J].IEEE Access,2019,7:104900-104911.
[4] YU T T,PRADEL M.SyncProf:Detecting,localizing,and optimizing synchronization bottlenecks[C]//Proceedings of the 25th International Symposium on Software Testing and Analysis.New York:Association for Computing Machinery,2016:389-400.
[5] 李夏君.物聯(lián)網(wǎng)應(yīng)用開發(fā)運用C#多線程異步編程的研究[J].信息與電腦(理論版),2018(5):162-165.
LI Xiajun.Research on application and development of IoT application using c# multithreaded asynchronous programming[J].China Computer & Communication,2018(5):162-165.
[6] RAVINDRANATH L,NATH S,PADHYE J,et al.Automatic and scalable fault detection for mobile applications[C]//Proceedings of the 12th Annual International Conference on Mobile systems,Applications,and Services.New York:Association for Computing Machinery,2014:190-203.
[7] LIN Y,RADOI C,DIG D.Retrofitting concurrency for android applications through refactoring[C]//Proceedings of the 22nd ACM SIGSOFT International Symposium on Foundations of Software Engineering.New York:Association for Computing Machinery,2014:341-352.
[8] LIN Y,DIG D.Refactorings for android asynchronous programming[C]//2015 30th IEEE/ACM International Conference on Automated Software Engineering(ASE).Lincoln:IEEE,2015:836-841.
[9] KIM M S,WELLINGS A.Refactoring asynchronous event handling in the real-time specification for java[C]//2009 21st Euromicro Conference on Real-Time Systems.Dublin,Ireland:IEEE,2009:25-34.
[10]HSIAO C H,NARAYANASAMY S,KHAN E M I,et al.AsyncClock:Scalable inference of asynchronous event causality[J].ACM SIGPLAN Notices,2017,52(4):193-205.
[11]JANIN D.An equational modeling of asynchronous concurrent programming[C]//Trends in Functional Programming.Springer,Cham:Springer Nature Switzerland,2020:180-203.
[12]VIEIRA H T,CAIRES L,SECO J C.The conversation calculus:a model of service-oriented computation[C]//Programming Languages and Systems.Berlin:Springer-Verlag Berlin Heidelberg,2008:269-283.
[13]ABADI M,KEIDAR-BARNER S,PIDAN D,et al.Verifying parallel code after refactoring using equivalence checking[J].International Journal of Parallel Programming,2019,47(1):59-73.
[14]KRISHNAN G P,TSANTALIS N.Unification and refactoring of clones[C]//2014 Software Evolution Week- IEEE Conference on Software Maintenance,Reengineering,and Reverse Engineering(CSMR-WCRE).Belgium:IEEE,2014:104-113.
[15]JURNEKA P,HANEK P,BARABAS M,et al.A method for parallel software refactoring for safety standards compliance[C]//8th IET International System Safety Conference incorporating the Cyber Security Conference 2013.Cardiff:IEEE,2013:1-6.
[16]ATKEY R,SANNELLA D.Threadsafe:Static analysis for java concurrency[J].Electronic Communications of the EASST,2015.doi:10.14279/tuj.eceasst.72.1025.
[17]NATH S,LIN F X Z,RAVINDRANATH L,et al.SmartAds:Bringing contextual ads to mobile apps[C]//Proceeding of the 11th Annual International Conference on Mobile systems.New York:Association for Computing Machinery,2013:111-124.
[18]鄭雅潔.并行程序中同步機(jī)制的軟件自動重構(gòu)方法研究與實現(xiàn)[D].石家莊:河北科技大學(xué),2018.
ZHENG Yajie.Research and Implementation of Software Automatic Refactoring Method for Synchronization Mechanism in Parallel Program[D].Shijiazhuang:Hebei University of Science and Technology,2018.
[19]邵帥.面向細(xì)粒度讀寫鎖的自動重構(gòu)方法研究[D].石家莊:河北科技大學(xué),2020.
SHAO Shuai.An Automated Refactoring Approach for Fine-grained Lock[D].Shijiazhuang:Hebei University of Science and Technology,2020.
[20]IBM T J.Watson Libraries for Analysis(WALA)[EB/OL].[2020-11-20].http://wala.sourceforge.net.
[21]WANG L,SUN X K.Escape analysis for synchronization removal[C]//Proceedings of the 2006 ACM Symposium on Applied Computing.New York:Association for Computing Machinery,2006:1419-1423.
[22]張楊,梁亞楠,張冬雯,等.并發(fā)程序中數(shù)據(jù)競爭檢測方法[J].計算機(jī)應(yīng)用,2019,39(1):61-65.
ZHANG Yang,LIANG Yanan,ZHANG Dongwen,et al.Data race detection approach in concurrent programs[J].Journal of Computer Applications,2019,39(1):61-65.
[23]ATHAIYA S,KOMONDOOR R,KUMAR K N.Data flow analysis of asynchronous systems using infinite abstract domains[C]//Programming Languages and Systems.Cham: Springer International Publishing,2021:30-58.