內(nèi)存拷貝函數(shù) memcpy 的原理及實(shí)現(xiàn)
內(nèi)存拷貝函數(shù)memcpy
memcpy是memory copy的縮寫,意為內(nèi)存復(fù)制,在寫C語言程序的時(shí)候,我們常常會(huì)用到它。它的函原型如下:
它的功能是從src的開始位置拷貝n個(gè)字節(jié)的數(shù)據(jù)到dest。如果dest存在數(shù)據(jù),將會(huì)被覆蓋。memcpy函數(shù)的返回值是dest的指針。memcpy函數(shù)定義在string.h頭文件里。自己實(shí)現(xiàn)的時(shí)候,最簡(jiǎn)單的方法是用指針按照字節(jié)順序復(fù)制即可。但是性能太低:
其一,一次一個(gè)字節(jié)效率太低,地址總線一般是32位,能搬運(yùn)4字節(jié),一次一個(gè)肯定慢的不行;
其二,當(dāng)內(nèi)存區(qū)域重疊時(shí)會(huì)出現(xiàn)混亂情況。
下邊根據(jù)以上兩方面考慮提高memcpy函數(shù)的性能。首先考慮速度,可以按照 CPU 位寬搬運(yùn)數(shù)據(jù),效率更高,代碼如下:
sizeof(dst)是4,即大部分?jǐn)?shù)據(jù)每次按照4字節(jié)拷貝,最后不足4字節(jié)的再分別拷貝。但是內(nèi)存區(qū)域出現(xiàn)重疊時(shí),這種方法無法規(guī)避內(nèi)存混亂問題。下面的方法能夠規(guī)避內(nèi)存重疊的bug,代碼如下:
如果檢測(cè)到內(nèi)存區(qū)域有重疊部分,則從末端開始對(duì)每個(gè)字節(jié)進(jìn)行拷貝。但數(shù)據(jù)量大時(shí)速度慢,將兩種方法結(jié)合后能夠提高拷貝函數(shù)性能,代碼如下:
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ?


零聲白金VIP體驗(yàn)卡(含基礎(chǔ)架構(gòu)/高性能存儲(chǔ)/golang/QT/音視頻/Linux內(nèi)核)課程:? ?

對(duì)比一下,測(cè)試代碼如下:
運(yùn)行結(jié)果:Memcpy1:1111333466558877990
Memcpy2:1111332466558877990
Memcpy:1111332466558877990?
后兩種方法正確,第一種方法拷貝時(shí)無法規(guī)避內(nèi)存重疊的bug。
原文作者:wykup
