在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【性能優(yōu)化】memcpy函數(shù)有沒有更高效的拷貝實現(xiàn)方法?

嵌入式物聯(lián)網(wǎng)開發(fā) ? 來源:嵌入式物聯(lián)網(wǎng)開發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開發(fā) ? 2022-12-07 08:59 ? 次閱讀

C語言經(jīng)典面試題】memcpy函數(shù)有沒有更高效的拷貝實現(xiàn)方法?

我相信大部分初中級C程序員在面試的過程中,可能都被問過關(guān)于memcpy函數(shù)的問題,甚至需要手撕memcpy。本文從另一個角度帶你領(lǐng)悟一下memcpy的面試題,你可以看看是否能接得???

1 寫在前面2 源碼實現(xiàn)2.1 函數(shù)申明2.2 簡單的功能實現(xiàn)2.3 滿足大數(shù)據(jù)量拷貝的功能實現(xiàn)3 源碼測試4 小小總結(jié)5 更多分享

1 寫在前面

假如你遇到下面的面試題,你會怎么做?題目大意如下:

請參考標準C庫對memcpy的申明定義,使用C語言的語法實現(xiàn)其基本功能,并盡量保證它在拷貝大數(shù)據(jù)(KK級別)的時候,有比較好的性能表現(xiàn)。

2 源碼實現(xiàn)

2.1 函數(shù)申明

通過查看man幫助,我們可以知道m(xù)emcpy函數(shù)的功能及其簡要申明。

NAME
        memcpy - copy memory area
 ?
 SYNOPSIS
        #include

英文翻譯過來就是說,memcpy實現(xiàn)的就是內(nèi)存拷貝,其是按字節(jié)進行拷貝,同時還可能會存在內(nèi)存區(qū)域重合的情況。

2.2 簡單的功能實現(xiàn)

根據(jù)功能需求,以下是我的一個簡單實現(xiàn)源碼,僅供參考:

char *my_memcpy(char* dest, const char *src, size_t len)
 {
     assert(dest && src && (len > 0));
 
 if (dest == src) {
 ;
 } else {
         char *p = dest;
 size_t i;
         for (i = 0; i < len; i++) {
             *p++ = *src++;
 }
     } 
 ?
     return dest;
 }

但是,這段代碼的缺陷也比較明顯,但數(shù)據(jù)量過大的時,即len很大時,整一個拷貝耗時將會非常不理想。那么如果考慮性能問題,又該如何實現(xiàn)它呢?

2.3 滿足大數(shù)據(jù)量拷貝的功能實現(xiàn)

下面給出一個參考實現(xiàn):

/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \\
 (((long)X & (sizeof(long) - 1)) | ((long)Y & (sizeof(long) - 1)))
 ?
 /* How many bytes are copied each iteration of the 4X unrolled loop.  */
 #define BIGBLOCKSIZE    (sizeof(long) << 2)
 ?
 /* How many bytes are copied each iteration of the word copy loop.  */
 #define LITTLEBLOCKSIZE (sizeof(long))
 ?
 /* Threshhold for punting to the byte copier.  */
 #define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
 ?
 char *my_memcopy_super(char* dest0, const char *src0, size_t len0)
 {
     assert(dest0 && src0 && (len0 > 0));
 
 char *dest = dest0;
 const char *src = src0;
 long *aligned_dest;
 const long *aligned_src;
 ?
 /* If the size is small, or either SRC or DST is unaligned,
    then punt into the byte copy loop.  This should be rare.  */
 if (!TOO_SMALL(len0) && !UNALIGNED(src, dest)) {
 aligned_dest = (long *)dest;
 aligned_src = (long *)src;
 ?
 /* Copy 4X long words at a time if possible.  */
 while (len0 >= BIGBLOCKSIZE) {
 *aligned_dest++ = *aligned_src++;
 *aligned_dest++ = *aligned_src++;
 *aligned_dest++ = *aligned_src++;
 *aligned_dest++ = *aligned_src++;
 len0 -= BIGBLOCKSIZE;
 }
 ?
 /* Copy one long word at a time if possible.  */
 while (len0 >= LITTLEBLOCKSIZE) {
 *aligned_dest++ = *aligned_src++;
 len0 -= LITTLEBLOCKSIZE;
 }
 ?
 /* Pick up any residual with a byte copier.  */
 dest = (char *)aligned_dest;
 src = (char *)aligned_src;
 }
 ?
 while (len0--)
 *dest++ = *src++;
 ?
 return dest0;
 }
 ?

我們可以看到,里面做了對齊的判斷,還有數(shù)據(jù)量長度的判斷;通過充分利用機器的操作性能,從而提升memcpy拷貝的效率。

3 源碼測試

**簡單的測試代碼如下,目的就是測試在拷貝 **1KB數(shù)據(jù)和10MB數(shù)據(jù) 時,標準C的memcpy、自定義的memcpy_normal、以及自定義的memcpy_super直接的性能差異:

#include 
 #include 
 ?
 static void get_rand_bytes(unsigned char *data, int len)
 {
     int a;
     int i;
 ?
     srand((unsigned)time(NULL)); //種下隨機種子
     for (i = 0; i < len; i++) {
         data[i] = rand() % 255; //取隨機數(shù),并保證數(shù)在0-255之間
         //printf("%02X ", data[i]);
     }  
 }
 ?
 static int get_cur_time_us(void)
 {
     struct timeval tv;
 ?
     gettimeofday(&tv, NULL);  //使用gettimeofday獲取當前系統(tǒng)時間
 ?
     return (tv.tv_sec * 1000 * 1000 + tv.tv_usec); //利用struct timeval結(jié)構(gòu)體將時間轉(zhuǎn)換為ms
 }
 ?
 #define ARRAY_SIZE(n)  sizeof(n) / sizeof(n[0])
 ?
 int main(void)
 {
 int size_list[] = {
 1024 * 1024 * 10,  // 10MB
 1024 * 1024 * 1,  // 1MB
 1024 * 100, // 100KB
 1024 * 10, // 10KB
 1024 * 1, // 1KB
 };
     char *data1;
     char *data2;
     int t1;
     int t2;
     int i = 0;
 ?
     data1 = (char *)malloc(size_list[0]);
     data2 = (char *)malloc(size_list[0]);
 ?
     get_rand_bytes(data1, size_list[0]);
 ?
     for (i = 0; i < ARRAY_SIZE(size_list); i++) {
     t1 = get_cur_time_us();
     memcpy(data2, data1, size_list[i]);
     t2 = get_cur_time_us();
     printf("copy %d bytes, memcpy_stdc   waste time %dus\\n", size_list[i], t2 - t1);
 ?
     t1 = get_cur_time_us();
     my_memcopy_normal(data2, data1, size_list[i]);
     t2 = get_cur_time_us();
     printf("copy %d bytes, memcpy_normal waste time %dus\\n", size_list[i], t2 - t1);
 ?
     t1 = get_cur_time_us();
     my_memcopy_super(data2, data1, size_list[i]);
     t2 = get_cur_time_us();
     printf("copy %d bytes, memcpy_super  waste time %dus\\n\\n", size_list[i], t2 - t1);
     }
 ?
     free(data1);
     free(data2);
 ?
 return 0;
 }
 ?

簡單執(zhí)行編譯后,運行小程序的結(jié)果:

image-20221205135556210

從運行結(jié)果上看:

  • **拷貝數(shù)據(jù)量比較小時,拷貝效率排行: **normal < super < stdc
  • **拷貝數(shù)據(jù)量比較大時,拷貝效率排行: **normal < stdc < super

4 小小總結(jié)

memcpy的源碼實現(xiàn),核心就是內(nèi)存拷貝,要想提升拷貝的效率,還得充分利用機器的運算性能,比如考慮對齊問題。

綜合來看,標準C庫實現(xiàn)的memcpy在大部分的場景下都可以有一個比較好的性能表現(xiàn),這一點是值得稱贊的。

5 更多分享

[架構(gòu)師李肯]

架構(gòu)師李肯全網(wǎng)同名 ),一個專注于嵌入式IoT領(lǐng)域的架構(gòu)師。有著近10年的嵌入式一線開發(fā)經(jīng)驗,深耕IoT領(lǐng)域多年,熟知IoT領(lǐng)域的業(yè)務(wù)發(fā)展,深度掌握IoT領(lǐng)域的相關(guān)技術(shù)棧,包括但不限于主流RTOS內(nèi)核的實現(xiàn)及其移植、硬件驅(qū)動移植開發(fā)、網(wǎng)絡(luò)通訊協(xié)議開發(fā)、編譯構(gòu)建原理及其實現(xiàn)、底層匯編及編譯原理、編譯優(yōu)化及代碼重構(gòu)、主流IoT云平臺的對接、嵌入式IoT系統(tǒng)的架構(gòu)設(shè)計等等。擁有多項IoT領(lǐng)域的發(fā)明專利,熱衷于技術(shù)分享,有多年撰寫技術(shù)博客的經(jīng)驗積累,連續(xù)多月獲得RT-Thread官方技術(shù)社區(qū)原創(chuàng)技術(shù)博文優(yōu)秀獎,榮獲[CSDN博客專家]、[CSDN物聯(lián)網(wǎng)領(lǐng)域優(yōu)質(zhì)創(chuàng)作者]、[2021年度CSDN&RT-Thread技術(shù)社區(qū)之星]、[2022年RT-Thread全球技術(shù)大會講師]、[RT-Thread官方嵌入式開源社區(qū)認證專家]、[RT-Thread 2021年度論壇之星TOP4]、[華為云云享專家(嵌入式物聯(lián)網(wǎng)架構(gòu)設(shè)計師)]等榮譽。堅信【知識改變命運,技術(shù)改變世界】!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4345

    瀏覽量

    62867
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1305

    瀏覽量

    40307
  • memcpy
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    2835
收藏 人收藏

    評論

    相關(guān)推薦

    【C語言經(jīng)典面試題】源碼實現(xiàn)標準庫函數(shù)memcpy

    你有面試中,要求寫memcpy的源碼實現(xiàn)嗎?本文給出一個參考寫法!
    的頭像 發(fā)表于 09-30 17:12 ?4190次閱讀

    高效率的內(nèi)存拷貝函數(shù)memcpy

    memcpy是memory copy的縮寫,意為內(nèi)存復(fù)制,在寫C語言程序的時候,我們常常會用到它。
    發(fā)表于 11-08 09:48 ?8559次閱讀

    HBase性能優(yōu)化方法總結(jié)

    讀密集型對于隨機讀密集型工作負載,高效利用緩存和更好地索引會給HBase系統(tǒng)帶來更高性能2. 順序讀密集型對于順序讀密集型工作負載,可以采用不使用緩存的方式減少硬盤訪問次數(shù)來提高性能
    發(fā)表于 04-20 17:16

    MSP430FRx MCU如何實現(xiàn)更高性能

    MSP MCU 的 MSP-IQMATHLIB 優(yōu)化型軟件庫可通過提供優(yōu)化型定點函數(shù)(包括加法、乘法、正弦和對數(shù))來幫助您縮短產(chǎn)品上市時間。 相較于采用標準 math.h 頭文件,這些函數(shù)
    發(fā)表于 09-10 11:57

    memCopy函數(shù)怎么實現(xiàn)拷貝的呢?

    memCopy函數(shù)是將指定地址的代碼拷貝到目的地址,一般情況下是把flash的代碼拷貝到ram內(nèi)運行,問題是:在flash啟動模式的情況下調(diào)用memcopy之前沒有初始化flash的等
    發(fā)表于 05-12 08:39

    STM32中的memcpy函數(shù)的使用 精選資料推薦

    定義是什么memcpy 函數(shù)用于 把資源內(nèi)存(src所指向的內(nèi)存區(qū)域) 拷貝到目標內(nèi)存(dest所指向的內(nèi)存區(qū)域);拷貝多少個?有一個size變量控制
    發(fā)表于 08-24 08:11

    memcpy怎么用_memcpy用法總結(jié)

    memcpy指的是c和c++使用的內(nèi)存拷貝函數(shù)memcpy函數(shù)的功能是從源src所指的內(nèi)存地址的起始位置開始
    發(fā)表于 11-28 15:56 ?4.7w次閱讀
    <b class='flag-5'>memcpy</b>怎么用_<b class='flag-5'>memcpy</b>用法總結(jié)

    淺談linux c編程中的拷貝函數(shù)

    strcpy: 最常用的字符串拷貝函數(shù),但是要注意這個函數(shù)不會自己判斷源字符串是否比目標空間大,必須要程序員自己檢查,否則很容易造成拷貝越界。
    發(fā)表于 05-31 01:46 ?2248次閱讀

    C++:詳談拷貝構(gòu)造函數(shù)

    只有單個形參,而且該形參是對本類類型對象的引用(常用const修飾),這樣的構(gòu)造函數(shù)稱為拷貝構(gòu)造函數(shù)。拷貝構(gòu)造函數(shù)是特殊的構(gòu)造
    的頭像 發(fā)表于 06-29 11:45 ?2158次閱讀
    C++:詳談<b class='flag-5'>拷貝</b>構(gòu)造<b class='flag-5'>函數(shù)</b>

    C語言模擬實現(xiàn)memcpy函數(shù)

    memcpy指的是c和c++使用的內(nèi)存拷貝函數(shù),memcpy函數(shù)的功能是從源src所指的內(nèi)存地址的起始位置開始
    的頭像 發(fā)表于 06-29 17:29 ?2518次閱讀
    C語言模擬<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>memcpy</b><b class='flag-5'>函數(shù)</b>

    C語言模擬實現(xiàn)memmove函數(shù)

    memmove用于從src拷貝count個字節(jié)到dest,如果目標區(qū)域和源區(qū)域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標區(qū)域中。但復(fù)制后src內(nèi)容會被更改。但是當目標區(qū)域與源區(qū)域沒有重疊則和
    的頭像 發(fā)表于 06-29 17:53 ?1791次閱讀
    C語言模擬<b class='flag-5'>實現(xiàn)</b>memmove<b class='flag-5'>函數(shù)</b>

    memcpy函數(shù)實現(xiàn)及其優(yōu)化

    函數(shù)原型void * memcpy ( void * destination, const void * source, size_t num );
    發(fā)表于 12-09 14:25 ?2733次閱讀

    C++之拷貝構(gòu)造函數(shù)的淺copy及深copy

    C++編譯器會默認提供構(gòu)造函數(shù);無參構(gòu)造函數(shù)用于定義對象的默認初始化狀態(tài);拷貝構(gòu)造函數(shù)在創(chuàng)建對象時拷貝對象的狀態(tài);對象的
    的頭像 發(fā)表于 12-24 15:31 ?781次閱讀

    C語言庫memcpy和memmove的區(qū)別分析

    memcpy和memmove都是 C 語言的庫函數(shù),相比于 strcpy和 strncpy只能針對于字符類型的數(shù)組(),這兩個函數(shù)可以拷貝其他類型的數(shù)組,對于
    發(fā)表于 09-19 12:19 ?2109次閱讀

    memcpy和memmove的區(qū)別是什么

    `memcpy`和`memmove`都是 C語言的庫函數(shù),相比于 `strcpy`和 `strncpy`只能針對于字符類型的數(shù)組(),這兩個函數(shù)可以拷貝其他類型的數(shù)組,對于 `
    的頭像 發(fā)表于 01-20 16:55 ?2707次閱讀
    <b class='flag-5'>memcpy</b>和memmove的區(qū)別是什么
    主站蜘蛛池模板: 狠狠的干狠狠的操 | 爱综合网| 与子乱刺激对白在线播放 | 91亚洲国产成人久久精品网站 | 97超频国产在线公开免费视频 | 久久视频精品36线视频在线观看 | 日本久草网 | dy888午夜秋霞影院不卡 | 可以免费看的黄色片 | 国产在线五月综合婷婷 | 免费看大尺度视频在线观看 | www色综合| 久久夜色精品国产噜噜小说 | 另类图片综合网 | 特黄一级黄色片 | a爱视频| 色噜噜狠狠狠色综合久 | 天天干天天综合 | 国产精品一区在线播放 | 男人j桶女人j免费视频 | tube44在线观看 | 午夜dy888理论| 色黄污在线看黄污免费看黄污 | 亚洲综合精品香蕉久久网97 | 国产一级毛片外aaaa | 啪啪调教所29下拉式免费阅读 | 日本黄免费 | 日本黄色的视频 | 宅男666在线永久免费观看 | 国产黄色网| 婷婷久久综合九色综合九七 | 草草影院www色极品欧美 | 爽爽爽爽爽爽a成人免费视频 | 一级久久久| 欧美性一区二区三区 | 中文字幕在线乱码免费毛片 | 五月桃花网婷婷亚洲综合 | 国产精品免费视频拍拍拍 | 亚洲1页| 黄视频在线观看免费 | 色午夜影院 |