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