一种memcpy函数的优化方法

文档序号:6510902阅读:2810来源:国知局
一种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日
【发明者】张福新, 陈杰, 王锐, 吴少刚, 张斌, 晏华 申请人:江苏中科梦兰电子科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1