專利名稱:一種基于配置文件的幫助線程構(gòu)造方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種基于配置文件的幫助線程構(gòu)造方法,屬于多核多線程技術(shù)領(lǐng)域。
背景技術(shù):
多核多線程技術(shù)是利用多核處理器中的多處理核來并發(fā)執(zhí)行多線程應(yīng)用程序的一項(xiàng)技術(shù)。片上多核處理器架構(gòu)通常具有共享的最后一級緩存。傳統(tǒng)的硬件預(yù)取可對應(yīng)用程序中的規(guī)則數(shù)據(jù)進(jìn)行預(yù)取,并提前送至該共享緩存中,當(dāng)應(yīng)用程序訪問到這些規(guī)則數(shù)據(jù)時,在共享緩存中便會找到所需數(shù)據(jù),而不用再進(jìn)行主存訪問。然而,對地址不連續(xù)的非規(guī)則數(shù)據(jù)訪問(如鏈表、非規(guī)則數(shù)組),由于訪問地址的不連續(xù)性,傳統(tǒng)硬件預(yù)取技術(shù)常會失效。這種情況下,基于幫助線程的預(yù)取技術(shù)被提出,它通過構(gòu)造應(yīng)用程序的預(yù)取幫助線程和使其在空閑核上執(zhí)行,來提前訪問這些非規(guī)則數(shù)據(jù),并及時推送它們到共享緩存中,以提高應(yīng)用程序的訪存性能。對用戶來說,人工設(shè)計(jì)這類預(yù)取幫助線程是一個困難任務(wù),建立自動生成輔助工具十分必要。這種困難主要表現(xiàn)在兩方面一、幫助線程與應(yīng)用程序間需要建立協(xié)同機(jī)制,以防止幫助線程因執(zhí)行太快造成的預(yù)取數(shù)據(jù)過早問題;也要防止幫助線程執(zhí)行過慢,導(dǎo)致應(yīng)用程序已訪問過這些數(shù)據(jù)、預(yù)取數(shù)據(jù)已無用的情況出現(xiàn)。二、應(yīng)用程序需知道幫助線程的執(zhí)行情況,而幫助線程也需知道應(yīng)用程序的執(zhí)行情況。雖然國際上已有基于代碼復(fù)制的幫助線程自動生成技術(shù),但它未能很好解決上述的預(yù)取過早或預(yù)取過晚等問題,難以確保幫助線程的構(gòu)造質(zhì)量?;谶@一原因,本發(fā)明實(shí)現(xiàn)了一種基于配置文件的幫助線程構(gòu)造方法。
發(fā)明內(nèi)容
本發(fā)明的目的是為克服上述問題,針對非規(guī)則數(shù)據(jù),提出一種基于配置文件的幫助線程構(gòu)造方法。該方法在減輕用戶或程序員編程困難的同時,通過引入預(yù)取提前量、預(yù)取量和同步量等控制變量,來對幫助線程預(yù)取過早或預(yù)取過晚等問題進(jìn)行有效控制。本發(fā)明可廣泛用于面向非規(guī)則應(yīng)用的多核編譯器優(yōu)化及數(shù)據(jù)庫性能的改進(jìn)。為了解釋我們方法所涉及的步驟中有關(guān)術(shù)語的含義,首先給出這些技術(shù)術(shù)語的定乂 定義I :熱函數(shù)對應(yīng)用程序P中的任一函數(shù)F (P),利用性能分析工具分別生成該函數(shù)F (P)和應(yīng)用程序P的片外訪存缺失計(jì)數(shù)和時鐘周期計(jì)數(shù),若該函數(shù)F (P)滿足“F (P)的片外訪存缺失計(jì)數(shù)/P的片外訪存缺失計(jì)數(shù)和F (P)的時鐘周期計(jì)數(shù)/P的時鐘周期計(jì)數(shù)均大于經(jīng)驗(yàn)閾值”,則F (P)是一個熱函數(shù)。定義2:熱數(shù)據(jù)區(qū)我們把熱函數(shù)所訪問的數(shù)據(jù)區(qū)域稱為一個熱數(shù)據(jù)區(qū)。定義3:配置文件針對一個非規(guī)則應(yīng)用程序P的多個熱數(shù)據(jù)區(qū),依次為每個熱數(shù)據(jù)區(qū)以字符串形式構(gòu)造出與幫助線程關(guān)聯(lián)的代碼區(qū)、幫助線程的控制變量組和幫助線程的“數(shù)據(jù)推送與同步變量”組,這些字符串經(jīng)合并后形成一個總字符串,并把該總字符串存為一個文件,我們稱該具有幫助線程構(gòu)造特征的文件為配置文件。本發(fā)明的一種基于配置文件的幫助線程構(gòu)造方法的整體框架設(shè)計(jì)流程如圖I所示,其特征在于其基本思想是在基于共享緩存的多核架構(gòu)基礎(chǔ)上,針對多核應(yīng)用中非規(guī)則數(shù)據(jù)缺失的問題,通過引入“構(gòu)造幫助線程的配置文件、構(gòu)造幫助線程的控制變量和初值、構(gòu)造幫助線程的生成代碼”等步驟,來自動生成幫助線程,以降低程序員或用戶的編程難度,提高應(yīng)用程序的執(zhí)行性能,并為多核編譯輔助工具提供有效的支撐技術(shù)。具體實(shí)現(xiàn)步驟如下步驟一、構(gòu)造幫助線程的配置文件在上述相關(guān)術(shù)語定義的基礎(chǔ)上,從應(yīng)用程序中人工或自動提取幫助線程的構(gòu)造特征,生成一個配置文件?;舅枷胧抢脩?yīng)用程序中的多個熱數(shù)據(jù)區(qū),通過提取它們的幫助線程構(gòu)造特征序列,經(jīng)合并后構(gòu)造出配置文件。其主要操作步驟如下第(I)步設(shè)置SUM總序列變量為空;依據(jù)定義I,確定應(yīng)用程序P中所有熱函數(shù)的集合HS ;從肥中選擇任一熱函數(shù)f (P)作為當(dāng)前需處理的熱函數(shù);第(2)步依據(jù)定義2確定該熱數(shù)據(jù)區(qū),提取和構(gòu)造其中與幫助線程相關(guān)的代碼區(qū)標(biāo)定序列A = ‘〈hot_spot_area>〈換行控制符>hotspotarea_begin=熱數(shù)據(jù)區(qū)的起始行號<換行控制符>hotspotarea_end=熱數(shù)據(jù)區(qū)的結(jié)束行號〈換行控制符>source_file=熱數(shù)據(jù)區(qū)所在的源文件名〈換行控制符〉funCti0n_name=熱數(shù)據(jù)區(qū)所在的函數(shù)名’;第(3)步設(shè)置該熱數(shù)據(jù)區(qū)的幫助線程控制變量組序列B = ‘a(chǎn)head_siZe=設(shè)定的預(yù)取提前量大小〈換行控制符>push_size=設(shè)定的預(yù)取量大小〈換行控制符>sync_size=設(shè)定的同步量大小’;這里ahead_size、push_size和sync_size均為一個非負(fù)整數(shù);第(4)步如果該熱數(shù)據(jù)區(qū)中不存在任何子區(qū),則依據(jù)性能分析工具的數(shù)據(jù)缺失標(biāo)注信息,從該熱數(shù)據(jù)區(qū)中提取和構(gòu)造幫助線程的“推送變量和同步變量”組序列C =‘hotspot_line=第I個推送變量所在的行號〈換行控制符>push_variable=第I個推送變量名〈換行控制符>*“hotspot_line=第η個推送變量所在的行號〈換行控制符>push_variable=第η個推送變量名〈換行控制符〉sync_variable=應(yīng)用程序和幫助線程間第I個同步變量名〈換行控制符〉…sync_variable=應(yīng)用程序和幫助線程間第m個同步變量名〈換行控制符>〈/h0t_sp0t_area>’ ;否則,如果推送變量在該熱數(shù)據(jù)區(qū)中的某個函數(shù)內(nèi)部,則需產(chǎn)生一個<child_hot_spot>. . . </child_hot_spot>子區(qū),從該熱數(shù)據(jù)區(qū)中提取和構(gòu)造幫助線程的“推送變量和同步變量”組序列C = ‘hotspotjine=推送變量所在的行號〈換行控制符>〈child_hot_spot>〈換行控制符>child_source_file=子區(qū)中該函數(shù)所在的文件〈換行控制符>child_function_name=子區(qū)中該函數(shù)名〈換行控制符>child_hotspot_line=子區(qū)第I個推送變量所在的行號〈換行控制符>child_push_variable=子區(qū)中第I個推送變量名〈換行控制符>“child_hotspot_line=子區(qū)第η個推送變量所在的行號〈換行控制符>child_push_variable=子區(qū)中第η個推送變量名〈換行控制符X/child_hot_spotX換行控制符>sync_variable=應(yīng)用程序和幫助線程間第I個同步變量名〈換行控制符>··· sync_variable=應(yīng)用程序和幫助線程間第m個同步變量名〈換行控制符>〈/hot_spot_area>,;
第(5 )步SUM = SUM+<換行控制符>+序列A+〈換行控制符>+序列B+〈換行控制符>+序列C ;第(6)步若HS中存在任何其他未處理的熱函數(shù),則轉(zhuǎn)第(2)步;否則,依據(jù)定義3,由SUM序列生成幫助線程的配置文件,并在第一行插入〈begin〉,最后一行插入〈/end〉,結(jié)束;步驟二、構(gòu)造幫助線程的控制變量和初值在步驟一構(gòu)造配置文件的基礎(chǔ)上,步驟二自動轉(zhuǎn)換配置文件序列中的數(shù)據(jù)為構(gòu)造幫助線程所需的控制變量和初值。其基本思想是將配置文件序列中的數(shù)據(jù)變換成構(gòu)造幫助線程代碼所需的控制變量和初值,并對推送變量和同步變量的初值進(jìn)行完整性驗(yàn)證和修正。其主要操作步驟如下第(I)步如果配置文件非空,將配置文件中的第一個<hot_spot_area>. . . </h0t_Sp0t_area>序列作為當(dāng)前的工作區(qū)(WA),并置WAC計(jì)數(shù)器為I;否則退出結(jié)束;第(2)步構(gòu)造當(dāng)前工作區(qū)的控制變量結(jié)構(gòu)為‘typedefstructpushVarlnfoNode{int line;string varName;int type;}pushVarlnfo;typedefstructsliceNode{int sliceStart;int siiceEnd;string sliceFunc;string sIiceFile;vector<pushVarInfo>var_push;vector<string>var_sync;int K, P,B;vector<string>var_depl;vector<string>var_dep2;SgStatement*copyed;}slice’,并將 slice[WAC]實(shí)例化為 slice;第(3)步從當(dāng)前工作區(qū)依序解析該<hot_spot_area>. . . </hot_spot_area> 序列, 并使 siiceStart=hotspotarea_begin, siiceEnd=hotspotarea_end, sliceFunc=function_name, sliceFile=source_file, K=ahead_size, P=push_size,B=sync_size ;var_push=push_variabIe 表,var_sync=sync_variable 表;第⑷步:依據(jù)slice [WAC]中 sliceStart, sliceEnd, sliceFunc 和 sliceFile 當(dāng)前的取值,標(biāo)定其在應(yīng)用程序P中的位置,并記錄所標(biāo)定區(qū)域的代碼到copyed變量中;第(5)步依據(jù)var_push和copyed的變量初值,搜索推送變量的所有依賴變量,并記錄到推送變量依賴表var_depl中,完成對var_push的驗(yàn)證和修正;具體可分步為5. I)首先將var_push初值放入推送變量依賴表var_depl中;5. 2)對推送變量依賴表var_cbpl中的每一項(xiàng),在copyed變量值中查找其直接依賴的推送變量,若存在新的依賴變量,將其放入var_depl中;5. 3)重復(fù)5. 2)直到?jīng)]有新的推送變量加入為止;第(6)步依據(jù)var_sync和copyed變量初值,在copyed變量值中搜索所有直接依賴的同步變量,并記錄到同步變量依賴表中var_dep2,完成對var_sync的驗(yàn)證和修正。具體可分步為6. I)首先將var_sync放入同步變量依賴表var_dep2中;6. 2)對同步依賴表var_cbp2中的每一項(xiàng),在copyed變量值中查找其直接依賴的同步變量,若存在新的同步變量,將其放入該var_cbp2中;6. 3)重復(fù)6. 2)直到?jīng)]有新的同步變量加入為止;第(7)步如果配置文件序列中還存在其他的‘〈hot_spot_area>. . . </hot_spot_area〉’子串,則選擇其中之一作為當(dāng)前工作區(qū),并置WAC計(jì)數(shù)器加1,轉(zhuǎn)第(2)步,否則結(jié)束。
步驟三、構(gòu)造幫助線程的生成代碼在步驟二構(gòu)造幫助線程控制變量和初值的基礎(chǔ)上,步驟三構(gòu)造幫助線程的生成代碼。其基本思想是依據(jù)幫助線程的控制變量和初值,自動生成幫助線程的代碼。主要操作步驟如下第(I)步分別在應(yīng)用程序P的main函數(shù)、幫助線程的push, h和push, c文件中增加構(gòu)造代碼,具體可分步為I. I)在main函數(shù)所在文件中加入幫助線程頭文件名push, h,該push, h頭文件中的代石馬包括iVoid init_pushthread O {pthread_create (&push_thread_id, O, push_thread_func, 0) ;}〈換行控制符 >void destroy_pushthread () {pthread_cancel (push_thread_id) ;}〈換行控制符 >...〈換行控制符 >#definePUSHDATA (ADDR) asm volatile (Vefetchtl (%0) 〃 〃r〃 (ADDR))〈換行控制符 >,等;I. 2)在main函數(shù)的開始部分,增加幫助線程的創(chuàng)建函數(shù)init_pushthread();在main函數(shù)返回前,調(diào)用該幫助線程終止函數(shù)destroy_pushthread O ;由于main函數(shù)可能有多個返回點(diǎn),在其中每一個返回點(diǎn)前,都需加上該幫助線程的終止函數(shù);I. 3)構(gòu)造 push, c 的 push_thread_func 為 ‘void*push_thread_func (void*arg)〈換行控制符>{for(;;)〈換行控制符>{···〈換行控制符>while(! (inter_push_flag!=’ \0’)) {<換行控制符>}〈換行控制符>switch(inter_push_flag) {<換行控制符>casel:〈換行控制符>{}〈換行控制符>case2:〈換行控制符>{}…〈換行控制符>}〈換行控制符>inter_push_flag=’ \0’ ; <換行控制符>} <換行控制符>} <換行控制符>’;I. 4)設(shè)置ss變量為I;第(2)步依據(jù)ss變量值修改push, c的push_thread_func代碼,具體可分步為2. I)在 push, c 的 push_thread_func 中,將 ‘case,+string (ss) + ‘ ,+〈換行控制符 >+ ‘{}’替換為‘case’+string (ss)+ ‘’+〈換行控制符 >+ ‘{’+ ‘slice’+string(ss)+ ‘();break;} ’ ;2. 2)為幫助線程的 push_thread_func 創(chuàng)建一個名為’ slice’ +string(ss)的空函數(shù),即當(dāng)ss=l時創(chuàng)建一個‘void slicel O {} ’或當(dāng)ss=2時創(chuàng)建一個‘void slice2 () {} ’等;第(3)步為使應(yīng)用程序與幫助線程之間能使用同步變量進(jìn)行共享操作,依據(jù)var_dep2初值和激活幫助線程函數(shù)所需的inter_push_f lag變量,在push, c文件的開始處加入inter_puSh_flag變量定義和全局共享的同步變量定義;第(4)步在該’slice’+String(SS)空函數(shù)中增加幫助線程代碼,具體可分步為4. I)增加全局共享的同步變量聲明定義;4. 2)針對 slice [ss]的 copyed 中記錄的熱函數(shù)代碼 ‘while (condition){whilebody;} ’,在該空函數(shù) ‘ 和 ’ 之間加入執(zhí)行代碼‘synchronization; while (condition){for(j=0 ; j〈B && condition ;j++){for(i=0;i〈K && condition;i++){push_whilebodyI;}for(i=0;i〈P&& condition;i++){push_whilebody2;}}synchronization;},;其中push_whilebodyl是在whilebody基礎(chǔ)上,通過對whilebody代碼經(jīng)由刪除“寫操作”的擇取生成的;push_whilebody2也是在whilebody基礎(chǔ)上,通過對whilebody代碼進(jìn)行刪除“寫操作”后擇取生成的,不過擇取過程必須依據(jù)Var_cbpl向量值,來完全刪除與數(shù)據(jù)預(yù)取無關(guān)的寫操作語句,以使幫助線程與應(yīng)用線程能夠并發(fā)執(zhí)行,并且不會對應(yīng)用線程運(yùn)行結(jié)果的正確性產(chǎn)生影響;‘synchronization’代碼是依據(jù)var_dep2值依次生成的;第(5)步優(yōu)化slice’ +string(ss)函數(shù),主要是將其中條件判斷語句或復(fù)雜語句進(jìn)行優(yōu)化,如將 if (condition) {Prefetch (a) ; Prefetch (b) ;} else {Prefetch (a) ;}變換為 Prefetch (a);Prefetch (b);第(6)步在SliCe[SS]所對應(yīng)的應(yīng)用程序“熱函數(shù)”中,加入全局共享的同步變量聲明定義,并設(shè)置激活幫助線程inter_push_flag變量的打開和關(guān)閉操作;第(7)步如果ss小于WAC,則ss=ss+l,轉(zhuǎn)第(2)步,否則結(jié)束。有益效果①本發(fā)明采用一種基于配置文件的幫助線程構(gòu)造方法,主要技術(shù)包括構(gòu)造幫助線程的配置文件、構(gòu)造幫助線程的控制變量和初值、構(gòu)造幫助線程的生成代碼,從而有效降低了編程的復(fù)雜性。與人工編程方式相比,有著不可比擬的便利性特點(diǎn)。②為幫助線程引入包含提前量、推送量和同步量等控制變量及經(jīng)驗(yàn)值,使得在應(yīng)用線程中無論有無足夠的計(jì)算工作,都能對過早或過晚的預(yù)取問題進(jìn)行有效控制。特別是在較少計(jì)算量的情況下,它可使應(yīng)用線程和幫助線程進(jìn)行更有效的交迭計(jì)算。③本發(fā)明可廣泛用于多核計(jì)算機(jī)編譯優(yōu)化和多核數(shù)據(jù)庫應(yīng)用的性能優(yōu)化。
圖I為本發(fā)明的整體框架設(shè)計(jì)流程具體實(shí)施例方式根據(jù)上述技術(shù)方案,下面結(jié)合實(shí)施例對本發(fā)明進(jìn)行詳細(xì)說明。以SPEC CPU 2006的標(biāo)準(zhǔn)測試程序mcf為例,給出相關(guān)術(shù)語的定義如下定義I :熱函數(shù)對應(yīng)用程序mcf中的refresh_potential函數(shù),利用性能分析工具VTUNE可發(fā)現(xiàn)MISS_C0UNT (refresh_potential (mcf)) /MISS_C0UNT (mcf) =3/5 和 CYCLE (refresh,potential (mcf ))/CYCLE (mcf)=29%,兩者均大于 25% 的閾值,則 refresh_potential 是一個熱函數(shù);同理可發(fā)現(xiàn)mcf中primal_bea_mpp也是一個熱函數(shù);定義2:熱數(shù)據(jù)區(qū)我們把該熱函數(shù)refresh_potential所訪問的數(shù)據(jù)區(qū)域稱為一個熱數(shù)據(jù)區(qū);定義3 :配置文件針對mcf 中 refresh_potential 和 primal_bea_mpp 熱函數(shù)及其熱數(shù)據(jù)區(qū),分別依次構(gòu)造其與幫助線程關(guān)聯(lián)的代碼區(qū)、幫助線程的控制變量組和幫助線程的“數(shù)據(jù)推送與同步變量”組等特征序列,合并形成一個如下的總字符串‘〈begin>〈換行控制符>〈hot_spot_area>〈換行控制符>hotspotarea_begin=84〈換行控制符>hotspotarea_end=l 12< 換行控制符 >source_f ile=〃mcfutil. c〃〈換行控制符 >function_name=〃refresh_potential〃〈換行控制符 >ahead_size=50〈換行控制符 >push_size=50〈換行控制符>sync_size=64<換行控制符>hotspot_line=89<換行控制符>push_variable=〃node->basic_arc->cost〃〈換行控制符 >hotspot_line=92〈換行控制符 >push_variable=〃node->basic_arc_>cost〃〈換行控制符 >sync_variable=〃tmp〃〈換行控制符 >sync—variable=〃root〃〈換行控制符 >sync—variable=〃node〃〈換行控制符 >〈/hot—spot—areaX 換行控制符 Xhot—spot—areaX 換行控制符 >hotspotarea—begin=173〈換行控制符 >hotspotarea—end=188〈換行控制符 >source—file=〃pbeampp. c〃〈換行控制符 >function—name=〃primal—bea—mpp〃〈換行控制符 >ahead—size=5〈換行控制符 >push—size=290<換行控制符>sync_size=l<換行控制符>hotspot_line=178<換行控制符>push—variable=〃arc->tail_>potential〃〈換行控制符 >hotspot—line=178〈換行控制符>push—variable=〃arc->head_>potential〈換行控制符 >〃sync—variable=〃nr—group〃〈換行控制符 >sync—variable=〃stop—arcs〃〈換行控制符 >sync—variable=〃arc〃〈換行控制符></hot_spot_area><換行控制符X/end〉’;我們把該總字符串所標(biāo)定的構(gòu)造特征序列存為一個配置文件。下面以包括兩個熱函數(shù)refresh—potential和primal—bea—mpp的應(yīng)用程序mcf為例,給出具體實(shí)施步驟步驟一、構(gòu)造幫助線程的配置文件第(I)步設(shè)置SUM序列為空;依據(jù)定義1,確定應(yīng)用程序mcf中的熱函數(shù)集合HS= {refresh—potential,primal—bea—mpp},并選擇 refresh—potential 作為當(dāng)前需處理的熱函數(shù);第(2)步依據(jù)定義2確定其熱數(shù)據(jù)區(qū),提取和構(gòu)造該熱數(shù)據(jù)區(qū)的序列A值如下‘〈hot—spot—areaX換行控制符>hotspotarea—begin=84〈換行控制符>hotspotarea_end=112< 換行控制符 >source—f ile=〃mcfutil. c〃〈換行控制符 >function—name=〃refresh—potential” ;第(3)步設(shè)置該熱數(shù)據(jù)區(qū)的序列B值如下‘a(chǎn)head—size=50〈換行控制符〉push—size=50〈換行控制符〉sync—size=64’ ;第(4)步因該熱數(shù)據(jù)區(qū)中不存在子區(qū),所以依據(jù)Vtune工具的數(shù)據(jù)缺失標(biāo)注信息,提取和構(gòu)造序列C值如下‘hotspot—Iine=89〈換行控制符>push—variable=〃node_>basic—arc_>cost〃〈換行控制符 >hotspot—line=92〈換行控制符 >push—variable=〃node_>basic—arc_>cost〃〈換行控制符 >sync—variable=〃tmp〃〈換行控制符>sync—variable=〃root〃〈換行控制符 >sync—variable=〃node〃〈換行控制符 >〈/hot—spot—area>,;第(5)步合并SUM、序列A、序列B和序列C到總序列SUM中,此時SUM值如下‘〈hot—spot—areaX 換行控制符 >hotspotarea—begin=84〈換行控制符 >hotspotarea—end=112< 換行控制符 >source—file=〃mcfutil. c〃〈換行控制符 >function_name=〃refresh—potential〃〈換行控制符 >ahead—size=50〈換行控制符 >push—size=50〈換行控制符>sync_size=64<換行控制符>hotspot_line=89<換行控制符>push_variable=〃node_>basic—arc_>cost〃〈換行控制符 >hotspot—line=92〈換行控制符 >push—variable=〃node_>basic—arc_>cost〃〈換行控制符 >sync—variable=〃tmp〃〈換行控制符>sync—variable=〃root〃〈換行控制符 >sync—variable=〃node〃〈換行控制符 >〈/hot—spot—area>’ ;第(6)步因HS中還存在著primal—bea—mpp熱函數(shù)未處理,須繼續(xù)執(zhí)行第(2)步到第(5)步一遍;此后,依據(jù)定義3生成完整的配置文件如下(并在第一行插入〈begin〉和最后一行插入〈/end〉): ‘〈beginX換行控制符Xhot—spot—areaX換行控制符 >hotspotarea—begin=84〈換行控制符 >hotspotarea—end=112〈換行控制符 >source—file=〃mcfutil. c〃〈換行控制符 >function—name=〃refresh—potential〃〈換行控制符>ahead_size=50<換行控制符>push—size=50〈換行控制符>sync—size=64〈換行控制符>hotspot_line=89< 換行控制符 >push—variable=〃node_>basic—arc_>cost〃〈換行控制符 >hotspot—line=92〈換行控制符 >push—variable=〃node_>basic—arc_>cost〃〈換行控制符 >sync—variable=〃tmp〃〈換行控制符 >sync—variable=〃root〃〈換行控制符 >sync—variable=〃node〃〈換行控制符 >〈/hot—spot—areaX 換行控制符 Xhot—spot—areaX 換行控制符 >hotspotarea—begin=173〈換行控制符 >hotspotarea—end=188〈換行控制符>source_file=//pbeampp. c"〈換行控制符 >function—name^primal—bea—mpp"〈換行控制符>ahead—size=5〈換行控制符>push—size=290〈換行控制符>sync—size=l〈換行控制符>hotspot_line=178< 換行控制符 >push—variable=〃arc->tail_>potential〃〈換行控制符 >hotspot—line=178〈換行控制符 >push—variable=〃arc->head_>potential〈換行控制符 >//sync_variable=//nr_group//< 換行控制符 >sync_variable=//stop_arcs//< 換行控制符>sync—variable=〃arc〃〈換行控制符 >〈/hot—spot—areaX 換行控制符 >〈/end>’ ;步驟二、構(gòu)造幫助線程的控制變量和初值第(I)步因上述配置文件非空,將配置文件中第一個熱數(shù)據(jù)區(qū)即potential 的〈hot—spot—area〉· · ·〈/hot—spot—area〉序列作為當(dāng)前工作區(qū)(WA),并置 WAC計(jì)數(shù)器為I ;第(2)步建立如下控制變量結(jié)構(gòu),并實(shí)例slice [WAC]為slice ‘typedefstructpushVarlnfoNode {int line;string varName;int type;} pushVarlnfo;typedefstructsliceNode{int sliceStart;int sliceEnd;string sliceFunc;stringsliceFile;vector<pushVarInfo> var_push;vector〈string〉var_sync;int K,P,B;vector <string>var_depl;vector<string>var_dep2;SgStatement氺copyed;}slice;’第(3)步解析幫助線程的控制變量和初值如下sliceStart=hotspotarea—begin=84, siiceEnd=hotspotarea_end=l12, siiceFunc=function_name=〃refresh_potential",sliceFile=source_file=〃mcfutil.c〃,var_push=push_variabIe=< push_variable= 〃node->basic_arc_>cost〃,push_variable=〃node->basic_arc_>cost〃>,var_sync=sync_variable=〈sync_variable=〃tmp〃,sync_variable = 〃root〃,sync_variable=〃node〃>,K=ahead—size=50,P=push_size=50,B=sync_size=64 ;第(4)步據(jù)sliceStart, sliceEnd, sliceFunc,sliceFile 的值,定位其在 mst 中的代碼區(qū)位置,并記錄到copyed變量中;第(5)步依據(jù)var—push和copyed的變量初值,在copyed變量值中搜索推送變量的所有依賴變量,并記錄到var—depl中,經(jīng)驗(yàn)證和修正得到〈push—variable=〃node->basic_arc_>cost〃, push_variable=〃node->basic_arc_>cost〃> ;第(6)步依據(jù)var—sync和copyed的變量初值,在copyed變量值中搜索同步變量的所有依賴變量,并記錄到var—dep2中,經(jīng)驗(yàn)證和修正得到〈sync—variable=〃tmp〃,sync—variable=〃root〃,sync_variable=〃node〃>;
12
第(7)步因還存在primal_bea_mpp熱數(shù)據(jù)區(qū),置WAC計(jì)數(shù)器加I,轉(zhuǎn)第(2)步再執(zhí)行一遍后結(jié)束;步驟三、構(gòu)造幫助線程的生成代碼第(I)步在main函數(shù)中增加如下代碼I. I)加入 #include"push. h",其中 push, h 主要包括
iVoid init pushlhreadO {ptliread_create( &push_thread_iciO, pushj;hread_func, O); {void destiOy_pushthread() {pthread_cancel(push_thread_id);}...
#define PUSH DATA (ADDR) asm volatile ("prefetchtl (%())":: "r"( ADDR))' Λ ;
1.2)在intmain(int argc,char *argv[])開始部分加入'initpushthreadO;
if (argc < 2) { destroy_pushthread( );ret.urn (-1);},;
1.3)構(gòu)iiiipush.c的push—thread—func為
void *push_t:hread_func(\Oid *arg)
/ — —
for (;;){_··
while(!(imer—push—flag != '\0')) {}switch( inter—push—flag)(case I:
.inter—push—flag = '\0';
} —1.4)置 ss=l;第(2)步依據(jù)ss變量值修改push, c的push_thread_func代碼,具體可分步為2. I)在 push, c 的 push_thread_func 中,將 ‘case,+string (ss) + ‘ ,+〈換行控制符 >+ ‘{}’替換為‘case’+string (ss)+ ‘’+〈換行控制符 >+ ‘{’+ ‘slice’+string(ss)+ ‘();break;} ’ ;2. 2)為幫助線程的 push_thread_func 創(chuàng)建一個名為’ slice’ +string(ss)的空函數(shù);第(3)步在push, c文件中加入全局共享的同步變量定義和激活幫助線程函數(shù)的 inter_push_flag 變量定義;如volatile int inter_push_fIag=O; arc_t*volatileg_s2_arc;arc_t*volatiIe g_s2_stop_arcs;volatile long g_s2_nr_group;node_t*volatileg_sl_tmp; ···;第(4)步在該’slice’+String(SS)空函數(shù)中增加幫助線程代碼,具體可分步為4. I)增加全局共享的同步變量聲明定義;4. 2)依據(jù)copyed,在slicel空函數(shù)中增加如下代碼void slicel ()
(extern nodet *voiatile g_s I _tmp;extern node」* volatile g_sl_root;extern node—t^volatile g_s l_node;node_t *node;node t * root; node—t *tmp;int tmp i;node =
g_sl_node;root = g_sl_root;tmp = gsltmp;
while(node != root) [for (tmp i = 0; tmp i < 50 && node != root; tmp i++)上while(node !— (0)) I
tmp = node;node = (node -> child): }node = tmp;
{while((node -> pred) != (0)) {tmp = (node -> sibling); if (tmp != (0)) {node =tmp;break; }
else {node = (node -> pred);.)}}for (tmp i = 0: tmp i < 50 && node != root; tmp i++) {while(node !- (0)) {
if ((node -> orientation) == I)(asm volatile ("prefetchtl (%0)"::"r'!(&(node->basic_arc->cost)));
}eise {
asm volatile ("prefetchtl ((H0)”::”r”(&(.nod.e->basic—arc->cost)));
}tmp = node;node = (node -> child);}node = tmp; {
\vhile((node -> pred) != (0))(tmp = (node -> sibling);if (tmp != (0)) {node = tmp;break;
} else {node = (node -> pred);}})}}node = NULL; root = NULL;tnip = NULL;}其中黑體部分是同步操作,畫線
部分是控制機(jī)制實(shí)現(xiàn)代碼。這里設(shè)置K、P、B參數(shù)分別設(shè)為50、50、0 ;第(5)步將node->potential=(((*(node->basic_arc))·cost)+ ((* (node_>pred) )· potential))復(fù)雜語句優(yōu)化為 node_>basic arc->cost 的預(yù)取語句;第(6)步在mcf的熱函數(shù)refresh_potential中加入全局共享的同步變量聲明定義,并設(shè)置幫助線程函數(shù)激活變量inter_push_flag的打開(inter_push_fIag=I)和關(guān)閉(inter_push_f Iag=O)操作;第(7)步因存在其他的熱數(shù)據(jù)區(qū)如primal_bea_mpp, ss變?yōu)?,轉(zhuǎn)第(2)步再執(zhí)
行一遍,然后結(jié)束。在Q6600計(jì)算機(jī)上,該mcf的綜合測試結(jié)果如下
權(quán)利要求
1.一種基于配置文件的幫助線程構(gòu)造方法,其特征在于其基本思想是在基于共享緩存的多核架構(gòu)基礎(chǔ)上,針對多核應(yīng)用中非規(guī)則數(shù)據(jù)缺失的問題,通過引入“構(gòu)造幫助線程的配置文件、構(gòu)造幫助線程的控制變量和初值、構(gòu)造幫助線程的生成代碼”等步驟,來自動生成幫助線程,以降低程序員或用戶的編程難度,提高應(yīng)用程序的執(zhí)行性能,并為多核編譯輔助工具提供有效的支撐技術(shù)。具體實(shí)現(xiàn)步驟如下 步驟一、構(gòu)造幫助線程的配置文件 利用應(yīng)用程序中的多個熱數(shù)據(jù)區(qū),人工或自動從中提取幫助線程的構(gòu)造特征序列,經(jīng)合并構(gòu)造后,生成一個配置文件。
步驟二、構(gòu)造幫助線程的控制變量和初值 在步驟一構(gòu)造的配置文件基礎(chǔ)上,步驟二自動轉(zhuǎn)換配置文件序列中的數(shù)據(jù)為構(gòu)造幫助線程所需的控制變量和初值,并對推送變量和同步變量的初值進(jìn)行完整性驗(yàn)證和修正。
步驟三、構(gòu)造幫助線程的生成代碼 在步驟二構(gòu)造的幫助線程控制變量和初值基礎(chǔ)上,步驟三構(gòu)造幫助線程的生成代碼。
2.根據(jù)權(quán)利要求I所述的一種基于配置文件的幫助線程構(gòu)造方法,其特征在于步驟一中構(gòu)造幫助線程的配置文件步驟為 第(I)步設(shè)置SUM總序列變量為空;依據(jù)定義1,確定應(yīng)用程序P中所有熱函數(shù)的集合HS ;從肥中選擇任一熱函數(shù)f (P)作為當(dāng)前需處理的熱函數(shù); 第(2)步依據(jù)定義2確定該熱數(shù)據(jù)區(qū),提取和構(gòu)造其中與幫助線程相關(guān)的代碼區(qū)標(biāo)定序列A = ‘〈hot_spot_area>〈換行控制符>hotspotarea_begin=熱數(shù)據(jù)區(qū)的起始行號〈換行控制符>hotspotarea_end=熱數(shù)據(jù)區(qū)的結(jié)束行號〈換行控制符>source_file=熱數(shù)據(jù)區(qū)所在的源文件名〈換行控制符〉function_name=熱數(shù)據(jù)區(qū)所在的函數(shù)名’; 第(3)步設(shè)置該熱數(shù)據(jù)區(qū)的幫助線程控制變量組序列B = ‘a(chǎn)head_siZe=設(shè)定的預(yù)取提前量大小〈換行控制符>push_size=設(shè)定的預(yù)取量大小〈換行控制符>sync_size=設(shè)定的同步量大小’;這里ahead_size、push_size和sync_size均為一個非負(fù)整數(shù); 第(4)步如果該熱數(shù)據(jù)區(qū)中不存在任何子區(qū),則依據(jù)性能分析工具的數(shù)據(jù)缺失標(biāo)注信息,從該熱數(shù)據(jù)區(qū)中提取和構(gòu)造幫助線程的“推送變量和同步變量”組序列C =‘hotspot_line =第I個推送變量所在的行號〈換行控制符> push_variable=第I個推送變量名〈換行控制符>*“hotspot_line=第η個推送變量所在的行號〈換行控制符>push_variable=第η個推送變量名〈換行控制符〉sync_variable=應(yīng)用程序和幫助線程間第I個同步變量名〈換行控制符>*“sync_variable=應(yīng)用程序和幫助線程間第m個同步變量名〈換行控制符>〈/h0t_sp0t_area>’ ;否則,如果推送變量在該熱數(shù)據(jù)區(qū)中的某個函數(shù)內(nèi)部,則需產(chǎn)生一個<child_hot_spot>. . . </child_hot_spot>子區(qū),從該熱數(shù)據(jù)區(qū)中提取和構(gòu)造幫助線程的“推送變量和同步變量”組序列C = ‘hotspotjine=推送變量所在的行號〈換行控制符>〈child_hot_spot>〈換行控制符>child_source_file=子區(qū)中該函數(shù)所在的文件〈換行控制符>child_function_name=子區(qū)中該函數(shù)名〈換行控制符>child_hotspot_line=子區(qū)第I個推送變量所在的行號〈換行控制符>child_push_variable=子區(qū)中第I個推送變量名〈換行控制符>“child_hotspot_line=子區(qū)第η個推送變量所在的行號〈換行控制符>child_push_variable=子區(qū)中第η個推送變量名〈換行控制符X/child_hot_spotX換行控制符>sync_variable=應(yīng)用程序和幫助線程間第I個同步變量名〈換行控制符>··· sync_variable=應(yīng)用程序和幫助線程間第m個同步變量名〈換行控制符>〈/hot_spot_area>,; 第(5)步SUM = SUM+<換行控制符>+序列A+〈換行控制符>+序列B+〈換行控制符>+序列C ; 第(6)步若HS中存在任何其他未處理的熱函數(shù),則轉(zhuǎn)第(2)步;否則,依據(jù)定義3,由SUM序列生成幫助線程的配置文件,并在第一行插入〈begin〉,最后一行插入〈/end〉,結(jié)束。
3.根據(jù)權(quán)利要求I所述的一種基于配置文件的幫助線程構(gòu)造方法,其特征在于步驟二構(gòu)造幫助線程的控制變量和初值步驟為 第(I)步如果配置文件非空,將配置文件中的第一個<hot_spot_area>. . . </hot_sp0t_area>序列作為當(dāng)前的工作區(qū)(WA),并置WAC計(jì)數(shù)器為I;否則退出結(jié)束; 第(2)步構(gòu)造當(dāng)前工作區(qū)的控制變量結(jié)構(gòu)為‘typedefstructpushVarlnfoNode{int line;string varName;int type;}pushVarlnfo;typedefstructsliceNode{int sliceStart;int sliceEnd;string siiceFunc;string sIiceFile;vector〈pushVarInfo>var_push;vector<string>var_sync;int K, P,B;vector<string>var_depl;vector<string>var_dep2;SgStatement*copyed;}slice’,并將 slice[WAC]實(shí)例化為 slice; 第(3)步從當(dāng)前工作區(qū)依序解析該<hot_spot_area>. . . </hot_spot_area>序列,并使,sliceStart=hotspotarea_begin, sliceEnd = hotspotarea_end, siiceFunc =function_name sliceFile=source_file,K = ahead_size,P = push_size,B = sync_size ;var_push=push_variab I e 表,var_sync=sync_variable 表; 第(4)步依據(jù) slice [WAC]中 sliceStart, sliceEnd, sliceFunc 和 sliceFile 當(dāng)前的取值,標(biāo)定其在應(yīng)用程序P中的位置,并記錄所標(biāo)定區(qū)域的代碼到copyed變量中; 第(5)步依據(jù)var_push和copyed的變量初值,搜索推送變量的所有依賴變量,并記錄到推送變量依賴表var_depl中,完成對var_push的驗(yàn)證和修正;具體可分步為 5.I)首先將var_push初值放入推送變量依賴表var_depl中; 5.2)對推送變量依賴表var_cbpl中的每一項(xiàng),在copyed變量值中查找其直接依賴的推送變量,若存在新的依賴變量,將其放入var_depl中; 5.3)重復(fù)5. 2)直到?jīng)]有新的推送變量加入為止; 第(6)步依據(jù)var_sync和copyed變量初值,在copyed變量值中搜索所有直接依賴的同步變量,并記錄到同步變量依賴表var_dep2中,完成對var_sync的驗(yàn)證和修正。具體可分步為 6.I)首先將var_sync放入同步變量依賴表var_dep2中; 6.2)對同步依賴表var_cbp2中的每一項(xiàng),在copyed變量值中查找其直接依賴的同步變量,若存在新的同步變量,將其放入該var_cbp2中; 6.3)重復(fù)6. 2)直到?jīng)]有新的同步變量加入為止; 第(7 )步如果配置文件序列中還存在其他的‘ <hot_spot_area>. . . </hot_spot_area〉’子串,則選擇其中之一作為當(dāng)前工作區(qū),并置WAC計(jì)數(shù)器加1,轉(zhuǎn)第(2)步,否則結(jié)束。
4.根據(jù)權(quán)利要求I所述的一種基于配置文件的幫助線程構(gòu)造方法,其特征在于步驟三構(gòu)造幫助線程的生成代碼步驟為 第(I)步分別在應(yīng)用程序P的main函數(shù)、幫助線程的push, h和push, c文件中增加構(gòu)造代碼,具體可分步為 I. I)在main函數(shù)所在文件中加入幫助線程頭文件名push, h,該push, h頭文件中的代石馬包括iVoid init_pushthread O {pthread_create (&push_thread_id, O, push_thread_func, 0) ;}〈換行控制符 >void destroy_pushthread () {pthread_cancel (push_thread_id) ;}〈換行控制符 〈換行控制符 >#definePUSHDATA (ADDR) asm volatile (VefetchtI (%0) 〃: : 〃r〃 (ADDR)) < 換行控制符 >’等; I. 2)在main函數(shù)的開始部分,增加幫助線程的創(chuàng)建函數(shù)init_pushthreadO ;在1]1&;[11函數(shù)返回前,調(diào)用該幫助線程終止函數(shù)destix)y_pushthread0 ;由于main函數(shù)可能有多個返回點(diǎn),在其中每一個返回點(diǎn)前,都需加上該幫助線程的終止函數(shù); I. 3)構(gòu)造 push.c 白勺 push_thread_func 為 <void*push_thread_func(void*arg)< 換行控制符 >{for(;;)〈換行控制符 >{···〈換行控制符 >while (! (inter_push_flag! =' \0’)){<換行控制符>} <換行控制符>switch (inter_push_flag) {<換行控制符>casel: <換行控制符> H〈換行控制符>case2: <換行控制符> {}… < 換行控制符>} <換行控制符>inter_push_f lag=’ \0’ ; <換行控制符>} <換行控制符>} <換行控制符>’; .1.4)設(shè)置ss變量為I; 第(2)步依據(jù)ss變量值修改push, c的push_thread_func代碼,具體可分步為.2.I)在 push, c 的 push_thread_func 中,將 ‘case’ +string (ss) + ‘ ’ +〈換行控制符 >+ ‘{}’替換為‘case’+string (ss)+ ‘’+〈換行控制符 >+ ‘{’+ ‘slice’+string(ss)+ ‘ O ;break;}’ ; .2.2)為幫助線程的push_thread_func創(chuàng)建一個名為’ slice’ +string(ss)的空函數(shù),即當(dāng) ss=l 時創(chuàng)建一個 ‘void slicel O {} ’ 或當(dāng) ss=2 時創(chuàng)建一個 ‘void slice2 O {} ’ 等;第(3)步為使應(yīng)用程序與幫助線程之間能使用同步變量進(jìn)行共享操作,依據(jù)var_dep2初值和激活幫助線程函數(shù)所需的inter_push_flag變量,在push, c文件的開始處加入inter_push_flag變量定義和全局共享的同步變量定義; 第(4)步在該’ slice’ +string (ss)空函數(shù)中增加幫助線程代碼,具體可分步為 .4.I)增加全局共享的同步變量聲明定義; .4. 2)針對slice[ss]的copyed中記錄的熱函數(shù)代碼‘while (condition){whilebody;} ’,在該空函數(shù) ‘ 和 ’ 之間加入執(zhí)行代碼‘synchronization; while (condition){for(j=0 ;j〈B && condition ; j ++){for(i=0;i<K && condition;i++){push_whilebodyI;}for(i=0;i〈P&& condition;i++){push_whilebody2;}}synchronization;},;其中push_whilebodyl是在whilebody基礎(chǔ)上,通過對whilebody代碼經(jīng)由刪除“寫操作”的擇取生成的;push_whilebody2也是在whilebody基礎(chǔ)上,通過對whilebody代碼進(jìn)行刪除“寫操作”后擇取生成的,不過擇取過程必須依據(jù)Var_cbpl向量值,來完全刪除與數(shù)據(jù)預(yù)取無關(guān)的寫操作語句,以使幫助線程與應(yīng)用線程能夠并發(fā)執(zhí)行,并且不會對應(yīng)用線程運(yùn)行結(jié)果的正確性產(chǎn)生影響;‘synchronization’代碼是依據(jù)var_dep2值依次生成的; 第(5)步優(yōu)化slice’ +string(ss)函數(shù),主要是將其中條件判斷語句或復(fù)雜語句進(jìn)行優(yōu)化,如將 if (condition) {Prefetch (a) ; Prefetch (b) ;} else {Prefetch (a) ;}變換為Prefetch(a);Prefetch (b); 第(6)步在slice[ss]所對應(yīng)的應(yīng)用程序“熱函數(shù)”中,加入全局共享的同步變量聲明定義,并設(shè)置激活幫助線程inter_pUsh_flag變量的打開和關(guān)閉操 作; 第(7)步如果ss小于WAC,則ss=ss+l,轉(zhuǎn)第(2)步,否則結(jié)束。
全文摘要
本發(fā)明涉及一種基于配置文件的幫助線程構(gòu)造方法,屬于多核多線程技術(shù)領(lǐng)域。在基于共享緩存的多核架構(gòu)基礎(chǔ)上,針對多核應(yīng)用中非規(guī)則數(shù)據(jù)缺失的問題,通過引入“構(gòu)造幫助線程的配置文件、構(gòu)造幫助線程的控制變量和初值、構(gòu)造幫助線程的生成代碼”等步驟,來自動生成幫助線程,以降低程序員或用戶的編程難度,提高應(yīng)用程序的執(zhí)行性能,并為多核編譯輔助工具提供有效的支撐技術(shù)。
文檔編號G06F9/44GK102929616SQ201210396209
公開日2013年2月13日 申請日期2012年10月18日 優(yōu)先權(quán)日2012年10月18日
發(fā)明者鄭寧漢, 古志民, 付引霞, 楊四才 申請人:北京理工大學(xué)