色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

【性能優化】memcpy函數有沒有更高效的拷貝實現方法?

嵌入式物聯網開發 ? 來源:嵌入式物聯網開發 ? 作者:嵌入式物聯網開發 ? 2022-12-07 08:59 ? 次閱讀

C語言經典面試題】memcpy函數有沒有更高效的拷貝實現方法?

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

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

1 寫在前面

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

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

2 源碼實現

2.1 函數申明

通過查看man幫助,我們可以知道memcpy函數的功能及其簡要申明。

NAME
        memcpy - copy memory area
 ?
 SYNOPSIS
        #include

英文翻譯過來就是說,memcpy實現的就是內存拷貝,其是按字節進行拷貝,同時還可能會存在內存區域重合的情況。

2.2 簡單的功能實現

根據功能需求,以下是我的一個簡單實現源碼,僅供參考:

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;
 }

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

2.3 滿足大數據量拷貝的功能實現

下面給出一個參考實現:

/* 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;
 }
 ?

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

3 源碼測試

**簡單的測試代碼如下,目的就是測試在拷貝 **1KB數據和10MB數據 時,標準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; //取隨機數,并保證數在0-255之間
         //printf("%02X ", data[i]);
     }  
 }
 ?
 static int get_cur_time_us(void)
 {
     struct timeval tv;
 ?
     gettimeofday(&tv, NULL);  //使用gettimeofday獲取當前系統時間
 ?
     return (tv.tv_sec * 1000 * 1000 + tv.tv_usec); //利用struct timeval結構體將時間轉換為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;
 }
 ?

簡單執行編譯后,運行小程序的結果:

image-20221205135556210

從運行結果上看:

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

4 小小總結

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

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

5 更多分享

[架構師李肯]

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

審核編輯:湯梓紅

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

    關注

    3

    文章

    4338

    瀏覽量

    62752
  • RT-Thread
    +關注

    關注

    31

    文章

    1296

    瀏覽量

    40238
  • memcpy
    +關注

    關注

    0

    文章

    9

    瀏覽量

    2834
收藏 人收藏

    評論

    相關推薦

    【C語言經典面試題】源碼實現標準庫函數memcpy

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

    高效率的內存拷貝函數memcpy

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

    HBase性能優化方法總結

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

    MSP430FRx MCU如何實現更高性能

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

    memCopy函數怎么實現拷貝的呢?

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

    STM32中的memcpy函數的使用 精選資料推薦

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

    memcpy怎么用_memcpy用法總結

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

    淺談linux c編程中的拷貝函數

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

    C++:詳談拷貝構造函數

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

    C語言模擬實現memcpy函數

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

    C語言模擬實現memmove函數

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

    memcpy函數實現及其優化

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

    C++之拷貝構造函數的淺copy及深copy

    C++編譯器會默認提供構造函數;無參構造函數用于定義對象的默認初始化狀態;拷貝構造函數在創建對象時拷貝對象的狀態;對象的
    的頭像 發表于 12-24 15:31 ?764次閱讀

    C語言庫memcpy和memmove的區別分析

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

    memcpy和memmove的區別是什么

    `memcpy`和`memmove`都是 C語言的庫函數,相比于 `strcpy`和 `strncpy`只能針對于字符類型的數組(),這兩個函數可以拷貝其他類型的數組,對于 `
    的頭像 發表于 01-20 16:55 ?2677次閱讀
    <b class='flag-5'>memcpy</b>和memmove的區別是什么
    主站蜘蛛池模板: 免费看片A级毛片免费看| 四虎国产精品免费观看视频| 丝袜足控免费网站xx91| 高肉黄暴NP文公交车| 窝窝午夜色视频国产精品东北| 国产成人在线播放视频| 亚洲国产日韩欧美在线a乱码| 精品国产乱码久久久久久人妻| 最近的中文字幕2019国语| 欧美亚洲色帝国| 国产乱人伦AV麻豆网| 伊人久久青草| 漂亮的av女演员| 国产精品爽爽久久久久久无码 | xart欧美一区在线播放| 日韩av无码在线直播| 果冻传媒在线观看进入窗口| 51精品国产AV无码久久久密桃| 日本电影护士| 好爽好深太大了再快一点| 99精品视频在线观看re| 小骚妇BBBXXX| 农村脱精光一级| 国产做国产爱免费视频| 99久久精品国产免费| 小草观看免费高清视频| 免费亚洲视频在线观看| 国产精品人妻无码久久久蜜桃臀 | 亚洲综合AV色婷婷五月蜜臀| 青青草原影视| 精品日韩视频| 国产AV午夜精品一区二区入口| 杨幂被视频在线观看| 肉肉的各种姿势高H细文| 快播欧美大片| 国产三级在线观看免费| av狼新人开放注册区| 亚洲手机在线人成视频| 十分钟免费观看高清视频大全| 男人J桶进男人屁股过程| 黄色软件视频app|