一種memcpy函數(shù)的優(yōu)化方法
【專利摘要】本發(fā)明公開了一種memcpy函數(shù)的優(yōu)化方法,包括以下步驟:1)通過單字節(jié)拷貝指令拷貝len長度的待拷貝數(shù)據,使源地址/目的地址中至少一個滿足N字節(jié)對齊,所述N為系統(tǒng)中位寬最高的指令一次能處理的字節(jié)個數(shù),即拷貝后源地址/目的地址滿足(x,N)或者(N,x)對齊,x為1,2,...,N;2)對于(x,N)對齊或者(N,x)對齊,分別以x字節(jié)指令或N字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由N字節(jié)指令或者x字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝。該方案使用盡可能高的位寬指令進行拷貝,提升了拷貝效率。
【專利說明】—種memcpy函數(shù)的優(yōu)化方法
【技術領域】
[0001]本發(fā)明涉及一種拷貝函數(shù)的優(yōu)化方法,特別是涉及一種memcpy函數(shù)的優(yōu)化方法?!颈尘凹夹g】
[0002]Memcpy函數(shù)是C語言的標準函數(shù),也是經常用的函數(shù),其作用將一份內存中的數(shù)據復制到另一內存位置。
[0003]現(xiàn)有優(yōu)化技術中,通過在memcpy函數(shù)的實現(xiàn)中使用高位寬的指令,例如使用一次復制8字節(jié)的指令替代一次復制4字節(jié)的指令,從而提高效率。
[0004]然而,高位寬的指令對地址的對齊有較高的要求。通常位寬為N的指令,對內存地址的對齊要求也是N。當memcpy函數(shù)的源地址/目的地址不滿足對齊要求時,在不同的硬件平臺上,或是不能使用這些高位寬的指令、或是指令的效能出現(xiàn)大幅度下降。
【發(fā)明內容】
[0005]針對上述現(xiàn)有技術的不足,本發(fā)明的目的是提供一種memcpy函數(shù)的優(yōu)化方法,盡可能源地址/目的地址達到高位寬對齊,從而使用高位寬讀寫指令完成拷貝任務,提升memcpy函數(shù)效率。
[0006]本發(fā)明的技術方案是這樣的:一種memcpy函數(shù)的優(yōu)化方法,其特征在于,包括以下步驟:
[0007]I)通過單字節(jié)拷貝指令 拷貝Ien長度的待拷貝數(shù)據,使源地址/目的地址中至少一個滿足N字節(jié)對齊,所述N為系統(tǒng)中位寬最高的指令一次能處理的字節(jié)個數(shù),即拷貝后源地址/目的地址滿足(X,N)或者(N, X)對齊,X為1,2,…,N ;
[0008]2)對于(x,N)對齊,以X字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由N字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝;對于(N,x)對齊,以N字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由X字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝。
[0009]在本發(fā)明的一個具體實施例中,所述Ien為源地址/目的地址除于N所得較大余數(shù)與N之間的差值。
[0010]在本發(fā)明的另一個具體實施例中,所述步驟I)之前判斷待拷貝數(shù)據長度是否大于效率臨界值,待拷貝數(shù)據長度大于效率臨界值時,進入步驟I);待拷貝數(shù)據長度小于等于效率臨界值時,由單字節(jié)拷貝指令完成拷貝。
[0011]本發(fā)明所提供的技術方案,針對源地址/目的地址較差的對齊情況,通過對源地址/目的地址對齊情況的“升級”,使用盡可能高的位寬指令進行讀寫來完成拷貝,相比原對齊狀況下使用受限指令的拷貝提升了拷貝效率,減少了拷貝延時,增強系統(tǒng)性能。通過判斷待拷貝數(shù)據長度是否超過效率臨界值,確定由優(yōu)化指令拷貝還是由單字節(jié)拷貝指令,避免由于待拷貝數(shù)據長度過短,造成優(yōu)化指令本身的效率損失無法通過整個拷貝過程效率的提升所彌補而使得優(yōu)化失敗,提升優(yōu)化指令的適用性?!緦@綀D】
【附圖說明】
[0012]圖1為本發(fā)明memcpy函數(shù)優(yōu)化后數(shù)據處理流程示意圖。
【具體實施方式】
[0013]下面結合實施例對本發(fā)明作進一步說明,但不作為對本發(fā)明的限定。 [0014]請參見圖1,首先對memcpy函數(shù)的參數(shù)說明:memcpy(dst, src, size),從內存地址src (源地址)開始,復制size個字節(jié)到內存地址dst (目標地址)。其中,如果src/dst整除4,則稱為源地址/目標地址為4字節(jié)對齊,如果src/dst整除8,則稱為源地址/目標地址為8字節(jié)對齊,依次類推。
[0015]現(xiàn)假設目前系統(tǒng)中位寬最高的指令一次能處理N個字節(jié),如果src/dst均是N字節(jié)對齊的,則效能最高。本發(fā)明的優(yōu)化主要針對src/dst不滿足N字節(jié)對齊的情況,先以單字節(jié)拷貝指令進行少量字節(jié)拷貝,使得拷貝后,src/dst的對齊狀況盡可能地“升級”。例如N=16,在src=15、dst=31情況下,兩地址均為非16字節(jié)對齊,進行單字節(jié)拷貝效率較低。在這里,我們先完成一個字節(jié)的拷貝,使得src=16,dst=32,此時兩者都是16字節(jié)對齊,可以使用16字節(jié)位寬指令來進行操作,以此提高效率。
[0016]具體地,在本實施例中,src/dst的對齊“升級”首先判斷src/dst除于N所得余數(shù)中較大者,由此較大余數(shù)與N之間的差值確定單字節(jié)拷貝長度;采用單字節(jié)拷貝命令對待拷貝數(shù)據進行拷貝,使源地址/目標地址逐一變化?!吧墶焙蟮膕rc/dst的對齊狀態(tài)必然為(x,N)或者(N,x) ;x取值為I,2,4,...,N,表示該地址為X字節(jié)對齊,目卩“升級后”,src/dst中至少有一個地址滿足N對齊,另一個地址則依據具體情況變?yōu)镮字節(jié)對齊或者2字節(jié)對齊或者4字節(jié)對齊,依次類推,出現(xiàn)的最佳狀況為“升級”后,源地址/目的地址均為N字節(jié)對齊。此處X的由src/dst除于N所得的余數(shù)差確定,余數(shù)差中所有2因子的乘積為X,余數(shù)差為O時,X取N,例如余數(shù)差為I時,具有O個2因子,x=2°=l,余數(shù)差為10時,具有I個2和一個5因子,x=21=2o升級后的src/dst,對于(x, N)對齊,以x字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由N字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝;對于(N,x)對齊,以N字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由X字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝。
[0017]一個更為完善,效率更高的memcpy函數(shù)優(yōu)化后的處理方式是這樣的:請結合圖1,memcpy中含有三個模塊:
[0018]A.任意對齊狀況拷貝模塊,該模塊能夠處理任意對齊狀況,但效率較差;
[0019]B.升級參數(shù)的計算模塊,計算“升級”后的對齊狀況是(x,N)還是(N,x)并確定X取值;計算“升級”所需拷貝的長度;
[0020]C.固定對齊狀況拷貝模塊,含有“2*log2N+l”個代碼塊對應處理(1,N)、(2,N)、(4,N),...(N, N)以及(N,N/2)、…(N,2)、(N, I)這 “2*log2N+l” 種對齊狀況;代碼塊中盡可能使用高位寬指令。
[0021]開始拷貝處理時,首先判斷memcpy參數(shù)中,size大小是否足夠,即待拷貝數(shù)據長度是否夠長。因為后續(xù)的優(yōu)化處理需要消耗一定的計算時間,size太小,優(yōu)化處理本身所耗時間無法從優(yōu)化所獲得的時間中得到彌補,則優(yōu)化效果不明顯甚至可能更慢。所以此處可以設定一個常數(shù),該常數(shù)為一個效率臨界值,當size小于該常數(shù)時,拷貝任務直接由A模塊完成,當size大于該常數(shù)時,進入B模塊處理,B模塊內容以偽代碼表示為:
[0022]a=src%N取源地址除于N后的余數(shù)
[0023]b=dst%N取目的地址除于N后的余數(shù)
[0024]Ien=N-MAX (a, b) “升級”過程需拷貝的數(shù)據長度
[0025]對于2*log2N+l種對齊狀況,可以用Y位(二進制位)數(shù)來表示。
[0026]Y=int(log2(2*log2N+l))+1
[0027]升級后狀況取的是(N,x)形式,還是(x,N)形式,并將對齊情況編碼成index
[0028]codel=cmp (a, b) a>=b 時,cmp 返回 I,否則返回 O
[0029]code2 表示(N, x)/ (x, N)中 x 的值
[0030]diff=a_b確定余數(shù)差
[0031]計算余數(shù)差中2因子的個數(shù)。實際上就是二進制表達下,低位連續(xù)的O的個數(shù)。這里用ctz函數(shù)(count trailing zeros)來表達這個功能。
[0032]set (diff, log2N+l)設置第log2N+l位,處理diff為O的特殊情況
[0033]code2=ctz (diff)
[0034]有的CPU直接支持等同功能指令,例如intel上bsr指令(從后往前尋找第一個被設置位的索引)則
[0035]code2=bsr (diff)
[0036]有的CPU支持近似指令,需要作轉換。例如MIPS上的clz指令(Count LeadingZeros)則通過diff和其相反數(shù)(計算機的補碼表達)按位進行與操作,從而獲得形如“000010000”的數(shù)。然后用寄存器總長word_len,減去高位連續(xù)O的個數(shù)以及中間的1,獲得低位連續(xù)的O的個數(shù)
[0037]codec2=word_len-clz(diff&-diff) -1
[0038]上述兩種CPU 下,index= (codel〈〈 (Y-1)) |code2。
[0039]B模塊完成后進入A模塊,按照B模塊獲得的Ien進行相應長度的數(shù)據拷貝進行對齊“升級”,然后進入C模塊。
[0040]C模塊中存在一個長度為21勺入口表(含有2*log2N+l個有效項),表中每個有效項存儲了 C模塊中處理固定對齊狀況的代碼塊起始地址。對于(X,N)對齊,以X字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由N字節(jié)指令從寄存器讀取數(shù)據存入目的地址;對于(N,x)對齊,以N字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由X字節(jié)指令從寄存器讀取數(shù)據存入目的地址。用B模塊獲得的index來索引C模塊入口表,便可得到C模塊中需要用到的代碼塊起始地址,進行拷貝。
[0041]而后判斷待拷貝數(shù)據是否全部處理完成,如完成則整個函數(shù)結束,如沒有完成則進入A模塊,完成余下的不能用高位寬指令處理的數(shù)據拷貝至函數(shù)結束。
【權利要求】
1.一種memcpy函數(shù)的優(yōu)化方法,其特征在于,包括以下步驟: 1)通過單字節(jié)拷貝指令拷貝Ien長度的待拷貝數(shù)據,使源地址/目的地址中至少一個滿足N字節(jié)對齊,所述N為系統(tǒng)中位寬最高的指令一次能處理的字節(jié)個數(shù),即拷貝后源地址/目的地址滿足(X,N)或者(N, X)對齊,X為1,2,…,N ; 2)對于(X,N)對齊,以X字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由N字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝;對于(N,x)對齊,以N字節(jié)指令從源地址讀取數(shù)據存入寄存器,再由X字節(jié)指令從寄存器讀取數(shù)據存入目的地址,剩余待拷貝數(shù)據不足N字節(jié)時由單字節(jié)指令進行拷貝。
2.根據權利要求1所述的memcpy函數(shù)的優(yōu)化方法,其特征在于:所述Ien為源地址/目的地址除于N所得較大余數(shù)與N之間的差值。
3.根據權利要求1所述的memcpy函數(shù)的優(yōu)化方法,其特征在于:所述步驟I)之前判斷待拷貝數(shù)據長度是否大于效率臨界值,待拷貝數(shù)據長度大于效率臨界值時,進入步驟I);待拷貝數(shù)據長度小于等于效率 臨界值時,由單字節(jié)拷貝指令完成拷貝。
【文檔編號】G06F9/44GK103473057SQ201310408259
【公開日】2013年12月25日 申請日期:2013年9月10日 優(yōu)先權日:2013年9月10日
【發(fā)明者】張福新, 陳杰, 王銳, 吳少剛, 張斌, 晏華 申請人:江蘇中科夢蘭電子科技有限公司