99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

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

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

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

【經(jīng)驗(yàn)分享】使用gettimeofday為你的程序運(yùn)行時(shí)間做統(tǒng)計(jì)

嵌入式物聯(lián)網(wǎng)開發(fā) ? 來(lái)源:嵌入式物聯(lián)網(wǎng)開發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開發(fā) ? 2022-12-07 09:00 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

C語(yǔ)言進(jìn)階】使用gettimeofday為你的程序運(yùn)行時(shí)間做統(tǒng)計(jì)

有時(shí)候在編程調(diào)試的時(shí)候,會(huì)遇到個(gè)別性能問題需要調(diào)試,這時(shí)候我們需要比較精確地統(tǒng)計(jì)每段代碼的耗時(shí)情況,這種情況下,你是怎么做的呢?本文介紹一種方法來(lái)實(shí)現(xiàn)此功能。

1 需求背景

2 簡(jiǎn)要分析

2.1 算法分析

2.2 gettimeofday簡(jiǎn)介

3 源碼實(shí)現(xiàn)

3.1 參考代碼

3.2 代碼簡(jiǎn)介

3.3 代碼測(cè)試

4 小小總結(jié)

5 更多分享

1 需求背景

在項(xiàng)目編程中,如果遇到調(diào)試代碼性能的時(shí)候,慢慢需要加時(shí)戳來(lái)觀察,找出那些耗時(shí)的操作。這種情況大部分需要人工干涉,如果我們需要程序自動(dòng)幫忙完成耗時(shí)分析呢?我們可以怎么做呢?

本文就這個(gè)場(chǎng)景問題,提供一種解決方案,歡迎大家參考。

2 簡(jiǎn)要分析

2.1 算法分析

根據(jù)我們的常識(shí),我們知道,要想知道一個(gè)操作的耗時(shí),一般的做法就是在操作前取一個(gè)時(shí)間,然后操作后取一個(gè)時(shí)間;最后兩個(gè)時(shí)間相減,得到的就是這段操作的耗時(shí)。

根據(jù)這里方法論,我們可以比較快地實(shí)現(xiàn)邏輯代碼,但是我們應(yīng)該用哪個(gè)函數(shù)取當(dāng)前時(shí)間點(diǎn)呢?

2.2 gettimeofday簡(jiǎn)介

Linux C語(yǔ)言編程中,我們很容易會(huì)想到gettimeofday這個(gè)函數(shù),下面我們將簡(jiǎn)單介紹一下這個(gè)函數(shù)。

參考Linux下的man說明,如下:

GETTIMEOFDAY(2) Linux Programmer's Manual GETTIMEOFDAY(2)

NAME

** gettimeofday, settimeofday - get / set time**

SYNOPSIS

** #include **

int gettimeofday(struct timeval *tv, struct timezone *tz);
 ?
 int settimeofday(const struct timeval *tv, const struct timezone *tz);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

settimeofday():
     Since glibc 2.19:
         _DEFAULT_SOURCE
     Glibc 2.19 and earlier:
         _BSD_SOURCE

DESCRIPTION

** The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone.**

The tv argument is a struct timeval (as specified in ):
 ?
     struct timeval {
         time_t      tv_sec;     /* seconds */
         suseconds_t tv_usec;    /* microseconds */
     };
 ?
 and gives the number of seconds and microseconds since the Epoch (see time(2)).
 ?
 The tz argument is a struct timezone:
 ?
     struct timezone {
         int tz_minuteswest;     /* minutes west of Greenwich */
         int tz_dsttime;         /* type of DST correction */
     };
 ?
 If either tv or tz is NULL, the corresponding structure is not set or returned.  (However, compilation warnings will result if tv is NULL.)
 ?
 The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.  (See NOTES below.)
 ?
 Under  Linux,  there are some peculiar "warp clock" semantics associated with the settimeofday() system call if on the very first call (after booting) that has a non-NULL tz argument,
 the tv argument is NULL and the tz_minuteswest field is nonzero.  (The tz_dsttime field should be zero for this case.)  In such a case it is assumed that the CMOS clock  is  on  local
 time, and that it has to be incremented by this amount to get UTC system time.  No doubt it is a bad idea to use this feature.

RETURN VALUE

** gettimeofday() and settimeofday() return 0 for success, or -1 for failure (in which case errno is set appropriately).**

從這里我們可以知道,gettimeofday用于獲取當(dāng)前的時(shí)間是非常容易的,它會(huì)將時(shí)間結(jié)果存儲(chǔ)在這個(gè)結(jié)構(gòu)體中:

struct timeval {

** time_t tv_sec; /* seconds */

** suseconds_t tv_usec; /* microseconds / *

** };

struct timeval 結(jié)構(gòu)體中有 tv_sec 秒?yún)?shù) 和 tv_usec 微妙參數(shù),非常有利于我們做時(shí)間的加減計(jì)算。

下面我們就用這個(gè)函數(shù)來(lái)實(shí)現(xiàn)下本期的功能。

3 源碼實(shí)現(xiàn)

3.1 參考代碼

本例給出一個(gè)參考代碼如下:

#include 
 #include 
 #include 
 #include 
 ?
 static int get_cur_time_ms(void)
 {
     struct timeval tv;
 ?
     gettimeofday(&tv, NULL);  //使用gettimeofday獲取當(dāng)前系統(tǒng)時(shí)間
 ?
     return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval結(jié)構(gòu)體將時(shí)間轉(zhuǎn)換為ms
 }
 ?

3.2 代碼簡(jiǎn)介

代碼的功能邏輯,正如上面 的函數(shù)描述所說,正是利用gettimeofday返回的struct timeval結(jié)構(gòu)內(nèi)的成員變量,通過秒、毫秒、微妙的數(shù)量轉(zhuǎn)換,將當(dāng)前時(shí)間轉(zhuǎn)換成毫秒,然后以函數(shù)返回值的形式輸出。

值得注意的是,雖然gettimeofday在結(jié)構(gòu)體定義上 【號(hào)稱】有微妙級(jí)的精度,但是實(shí)際大部分的平臺(tái)是沒法達(dá)到這樣的精度的,所以我們?nèi)∑渲?,轉(zhuǎn)換成毫秒級(jí)的精度,這個(gè)已經(jīng)滿足我們絕大多數(shù)應(yīng)用場(chǎng)景了。

3.3 代碼測(cè)試

針對(duì)上面的功能代碼,寫了一段小代碼來(lái)測(cè)試下。

#include 
 #include 
 #include 
 #include 
 ?
 static int get_cur_time_ms(void)
 {
     struct timeval tv;
 ?
     gettimeofday(&tv, NULL);  //使用gettimeofday獲取當(dāng)前系統(tǒng)時(shí)間
 ?
     return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval結(jié)構(gòu)體將時(shí)間轉(zhuǎn)換為ms
 }
 ?
 static void get_rand_bytes(unsigned char *data, int len)
 {
     int a;
     int i;
 ?
     srand((unsigned)time(NULL)); //種下隨機(jī)種子
     for (i = 0; i < len; i++) {
         data[i] = rand() % 255; //取隨機(jī)數(shù),并保證數(shù)在0-255之間
         //printf("%02X ", data[i]);
     }  
 }
 ?
 int main(int argc, const char **argv)
 {
     int t1;
     int t2;
     unsigned char data[1024000];
 ?
     t1 = get_cur_time_ms();
     get_rand_bytes(data, sizeof(data));
     t2 = get_cur_time_ms();
     printf("random %d bytes, waste time: %dms
", sizeof(data), t2 - t1); //打印耗時(shí)
 ?
     return 0;
 }
 ?

以下測(cè)試代碼的邏輯還是很簡(jiǎn)單的,主要就是測(cè)試獲取 1024000個(gè)隨機(jī)數(shù)的耗時(shí)情況。

image-20221205132449215

由于我本次測(cè)試使用的PC主機(jī),其性能還是不錯(cuò),所以測(cè)試出來(lái)的數(shù)據(jù),還是耗時(shí)比較小的;如果這段代碼放在嵌入式平臺(tái)去運(yùn)行的話,一個(gè)可能data數(shù)組的內(nèi)存會(huì)爆,第二個(gè)耗時(shí)可能會(huì)大大增加。

感興趣的朋友可以拿去一試。

注,本次測(cè)試的PC機(jī)情況如下:

image-20221205132334585

4 小小總結(jié)

  • 面對(duì)需求說明,盡快找到核心的功能要點(diǎn),找到算法邏輯是關(guān)鍵;
  • 明白要做什么,再去選擇合適的函數(shù)來(lái)滿足功能邏輯,這是比較好的思路;
  • 考慮到gettimeofday的實(shí)際精度問題,犧牲部分不起眼的精度,依然可以滿足大部分的需求。

5 更多分享

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

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

審核編輯:湯梓紅

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

    關(guān)注

    32

    文章

    1412

    瀏覽量

    41989
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何縮短Vivado的運(yùn)行時(shí)間

    在Vivado Implementation階段,有時(shí)是有必要分析一下什么原因?qū)е?b class='flag-5'>運(yùn)行時(shí)間(runtime)過長(zhǎng),從而找到一些方法來(lái)縮短運(yùn)行時(shí)間。
    的頭像 發(fā)表于 05-29 14:37 ?1.5w次閱讀
    如何縮短Vivado的<b class='flag-5'>運(yùn)行時(shí)間</b>

    獲取單片機(jī)運(yùn)行時(shí)間

    的開始階段使單片機(jī)的一個(gè)GPIO輸出高電平,在待測(cè)程序段的結(jié)尾階段再令這個(gè)GPIO輸出低電平。用示波器通過檢查高電平的時(shí)間長(zhǎng)度,就知道了這段代碼的運(yùn)行時(shí)間。顯然,借助于示波器的方法更為簡(jiǎn)便。 以下內(nèi)容
    的頭像 發(fā)表于 08-26 20:26 ?2233次閱讀
    獲取單片機(jī)<b class='flag-5'>運(yùn)行時(shí)間</b>

    如何檢查L(zhǎng)inux服務(wù)器的運(yùn)行時(shí)間

    Linux 中的 uptime 用于查看系統(tǒng)啟動(dòng)后的運(yùn)行時(shí)間。它是一個(gè)比較簡(jiǎn)單的 Linux 命令,可以不帶參數(shù)直接運(yùn)行。
    發(fā)表于 11-25 15:25 ?1.6w次閱讀
    如何檢查L(zhǎng)inux服務(wù)器的<b class='flag-5'>運(yùn)行時(shí)間</b>

    labview如何實(shí)時(shí)獲取程序運(yùn)行時(shí)間?。。?!

    我們?cè)谧鲆粋€(gè)交通燈系統(tǒng),(交通燈倒計(jì)時(shí)時(shí)間用做的數(shù)碼管顯示)當(dāng)數(shù)碼管顯示3,2,1時(shí),交通燈要亮黃燈,我做了一個(gè)條件語(yǔ)句,當(dāng)時(shí)間在0~3之間時(shí)亮黃燈,否則其他燈亮。。但是不知道怎么獲取程序運(yùn)行
    發(fā)表于 12-26 00:30

    CCS 程序時(shí)間統(tǒng)計(jì)

    請(qǐng)教關(guān)于CCS 程序時(shí)間統(tǒng)計(jì)的問題: 能否指導(dǎo)simulator和emulator下各自測(cè)試代碼運(yùn)行時(shí)間的具體方法(程序實(shí)例或文檔),所給的方法能客觀地度量
    發(fā)表于 06-24 02:07

    LabVIEW程序運(yùn)行時(shí)間與循環(huán)時(shí)間沖突

    的是:1,如何使循環(huán)讀取的時(shí)間運(yùn)行時(shí)間一致; 2,使用定時(shí)循環(huán)結(jié)構(gòu)設(shè)定循環(huán)時(shí)間為什么不能達(dá)到循環(huán)時(shí)間運(yùn)行時(shí)間一致。
    發(fā)表于 11-30 14:24

    C語(yǔ)言教程之顯示程序運(yùn)行時(shí)間

    C語(yǔ)言教程之顯示程序運(yùn)行時(shí)間,很好的C語(yǔ)言資料,快來(lái)學(xué)習(xí)吧。
    發(fā)表于 04-25 16:09 ?0次下載

    如何用SysTick實(shí)現(xiàn)測(cè)量程序運(yùn)行時(shí)間

    在實(shí)際的項(xiàng)目開發(fā)過程中,常常遇到需要得到一段代碼的運(yùn)行時(shí)間,通常的方法是用示波器來(lái)測(cè)量,這篇博文將用 SysTick 來(lái)實(shí)現(xiàn) 精確測(cè)量 程序運(yùn)行時(shí)間。 STM32F4 的內(nèi)核定時(shí)
    的頭像 發(fā)表于 05-09 14:07 ?6438次閱讀
    如何用SysTick實(shí)現(xiàn)測(cè)量<b class='flag-5'>程序</b><b class='flag-5'>運(yùn)行時(shí)間</b>

    電機(jī)運(yùn)行時(shí)間進(jìn)行排列 是分為兩個(gè)部分來(lái)完成這個(gè)程序的設(shè)計(jì)的

    前幾天有個(gè)學(xué)員咨詢一個(gè)程序設(shè)計(jì)的問題,程序的控制要求如下:需要控制5臺(tái)電機(jī)的運(yùn)行,每臺(tái)電機(jī)運(yùn)行時(shí)需要記錄運(yùn)行時(shí)間,電機(jī)啟動(dòng)
    的頭像 發(fā)表于 07-19 08:57 ?7902次閱讀
    電機(jī)<b class='flag-5'>運(yùn)行時(shí)間</b>進(jìn)行排列 是分為兩個(gè)部分來(lái)完成這個(gè)<b class='flag-5'>程序</b>的設(shè)計(jì)的

    如何高效測(cè)量ECU的運(yùn)行時(shí)間

    ,最終可能會(huì)引起運(yùn)行時(shí)間方面的問題。這在項(xiàng)目后期需要大量的時(shí)間和金錢來(lái)解決。如果不能掌握系統(tǒng)的運(yùn)行狀態(tài),則很難發(fā)現(xiàn)系統(tǒng)內(nèi)缺陷的根源。 解決方案 將TA軟件工具套件與VX1000測(cè)量標(biāo)定硬件相結(jié)合,可同步分析 ECU內(nèi)部
    的頭像 發(fā)表于 10-28 11:05 ?2577次閱讀

    淺析STM32代碼運(yùn)行時(shí)間的技巧

    前言 ????測(cè)試代碼的運(yùn)行時(shí)間的兩種方法: 使用單片機(jī)內(nèi)部定時(shí)器,在待測(cè)程序段的開始啟動(dòng)定時(shí)器,在待測(cè)程序段的結(jié)尾關(guān)閉定時(shí)器。為了測(cè)量的準(zhǔn)確性,要進(jìn)行多次測(cè)量,并進(jìn)行平均取值。 借助示波器的方法
    的頭像 發(fā)表于 11-09 09:52 ?4296次閱讀
    淺析STM32代碼<b class='flag-5'>運(yùn)行時(shí)間</b>的技巧

    ch32v307記錄程序運(yùn)行時(shí)間

    ch32v307記錄程序運(yùn)行時(shí)間程序開發(fā)中,很重要的一項(xiàng)任務(wù)就是對(duì)程序運(yùn)行時(shí)間進(jìn)行評(píng)估。對(duì)于大型的
    的頭像 發(fā)表于 08-22 15:53 ?1292次閱讀

    西門子SCL編程50臺(tái)電機(jī)運(yùn)行時(shí)間累計(jì)方法

    當(dāng)RUN信號(hào)為TRUE時(shí),開始計(jì)時(shí),FALSE時(shí)停止計(jì)時(shí),單次運(yùn)行時(shí)間清零,長(zhǎng)按RESET5秒時(shí),單次和總運(yùn)行時(shí)間都清零。
    發(fā)表于 11-27 09:59 ?2728次閱讀
    西門子SCL編程50臺(tái)電機(jī)<b class='flag-5'>運(yùn)行時(shí)間</b>累計(jì)方法

    jvm運(yùn)行時(shí)內(nèi)存區(qū)域劃分

    JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,它是Java編程語(yǔ)言的運(yùn)行環(huán)境。JVM的主要功能是將Java源代碼轉(zhuǎn)換為機(jī)器代碼,并且在運(yùn)行時(shí)管理Java程序的內(nèi)存。JVM
    的頭像 發(fā)表于 12-05 14:08 ?750次閱讀

    三菱plc累計(jì)運(yùn)行時(shí)間怎么編程

    具有重要意義。本文將詳細(xì)介紹如何使用三菱PLC編程實(shí)現(xiàn)累計(jì)運(yùn)行時(shí)間統(tǒng)計(jì)功能。 一、概述 累計(jì)運(yùn)行時(shí)間是指設(shè)備或系統(tǒng)在一定時(shí)間內(nèi)的總運(yùn)行時(shí)間
    的頭像 發(fā)表于 06-20 11:31 ?3640次閱讀