日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 程序喵大人

memcpy在C/C++開發(fā)中很常用,面試時候也會經(jīng)常被問到memcpy和memmove的區(qū)別,本文先介紹下memcpy的原理。

可能各個平臺的實現(xiàn)原理不同,但都大同小異,本文主要介紹glibc中的memcpy。

基本定義

/* 函數(shù)原型 */ void *memcpy(void *dest, const void *src, size_t n);

memcpy的功能是將src指向的內存區(qū)域的前n個字節(jié)復制到dest指向的內存區(qū)域。

使用memcpy,需要注意以下幾點:

  1. 不處理重疊區(qū)域(這是memmove的職責)
  2. 返回目標地址dest
  3. 要求調用者確保:
    1. dest和src都是有效指針
    2. 內存區(qū)域不重疊
    3. 有足夠的空間

實現(xiàn)策略

glibc的memcpy實現(xiàn)采用了三層復制策略:

  1. 字節(jié)復制(Byte Copy)
  2. 字復制(Word Copy)
  3. 頁復制(Page Copy)

面試時候回答出三層復制策略這個關鍵點就很加分了。

核心實現(xiàn)

整體策略大體如下

  1. 數(shù)據(jù)量小于16字節(jié):
    1. 直接使用字節(jié)復制
    2. 避免對齊開銷
  2. 數(shù)據(jù)量在16字節(jié)到16KB之間(不一定是16KB,為了方便起見,統(tǒng)一使用16,你理解原理即可):
    1. 先對齊
    2. 使用字復制
    3. 處理剩余字節(jié)
  3. 數(shù)據(jù)量大于16KB:
    1. 先對齊
    2. 嘗試頁復制
    3. 字復制處理剩余數(shù)據(jù)
    4. 字節(jié)復制處理尾部

代碼詳見:

void * MEMCPY (void *dstpp, const void *srcpp, size_t len) { unsigned long int dstp = (long int) dstpp; unsigned long int srcp = (long int) srcpp; /* 保存原始目標地址用于返回 */ void *orig_dstpp = dstpp; /* 對于足夠大的數(shù)據(jù)塊,使用優(yōu)化策略 */ if (len >= OP_T_THRES)
 { /* 1. 首先對齊目標地址 */ len -= (-dstp) % OPSIZ;
 BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); /* 2. 嘗試頁復制 */ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); /* 3. 使用字復制處理剩余數(shù)據(jù) */ WORD_COPY_FWD (dstp, srcp, len, len);
 } /* 4. 處理剩余字節(jié) */ BYTE_COPY_FWD (dstp, srcp, len); return orig_dstpp;
}

詳細分析

字節(jié)復制

最基礎的復制方式,一次復制一個字節(jié):

#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)             \
 do                        \
 {                       \
 size_t __nbytes = (nbytes);               \
 while (__nbytes > 0)                  \
 {                     \
 byte __x = ((byte *) src_bp)[0];              \
 src_bp += 1;                    \
 __nbytes -= 1;                  \
 ((byte *) dst_bp)[0] = __x;               \
 dst_bp += 1;                    \
 }                     \
 } while (0) 

使用場景:

  • 小數(shù)據(jù)量復制
  • 處理非對齊數(shù)據(jù)
  • 處理剩余字節(jié)

字復制

按機器字長進行復制,提高效率:

#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)          \
 do                        \
 {                       \ if (src_bp % OPSIZ == 0)                  \
 _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);       \ else \
 _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);        \
 src_bp += (nbytes) & -OPSIZ;                \
 dst_bp += (nbytes) & -OPSIZ;                \
 (nbytes_left) = (nbytes) % OPSIZ;               \
 } while (0) 

優(yōu)化特點:

  • 利用CPU字長進行批量復制
  • 要求內存對齊
  • 比字節(jié)復制更高效

頁復制

最高效的復制方式,適用于大塊數(shù)據(jù):

#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)              \
 do {                                                                      \ if ((nbytes) >= PAGE_COPY_THRESHOLD                                     \
 && PAGE_OFFSET ((dstp) - (srcp)) == 0)                             \
 {                                                                       \ /* 處理第一個不完整頁 */ \
 size_t nbytes_before = PAGE_OFFSET (-(dstp));                        \ if (nbytes_before != 0)                                              \
 {                                                                   \
 WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before);          \
 nbytes -= nbytes_before;                                         \
 }                                                                   \ /* 執(zhí)行頁復制 */ \
 PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes);                    \
 }                                                                       \
 } while (0) #define PAGE_COPY_THRESHOLD      (16384) #define PAGE_SIZE    __vm_page_size #define PAGE_COPY_FWD(dstp, srcp, nbytes_left, nbytes)               \
 ((nbytes_left) = ((nbytes)                       \
 - (__vm_copy (__mach_task_self (),             \
 (vm_address_t) srcp, trunc_page (nbytes),   \
 (vm_address_t) dstp) == KERN_SUCCESS       \
 ? trunc_page (nbytes)                 \
 : 0)))


本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉