0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【经验分享】使用gettimeofday为你的程序运行时间做统计

嵌入式物联网开发 来源:嵌入式物联网开发 作者:嵌入式物联网开发 2022-12-07 09:00 次阅读

C语言进阶】使用gettimeofday为你的程序运行时间做统计

有时候在编程调试的时候,会遇到个别性能问题需要调试,这时候我们需要比较精确地统计每段代码的耗时情况,这种情况下,你是怎么做的呢?本文介绍一种方法来实现此功能。

1 需求背景

2 简要分析

2.1 算法分析

2.2 gettimeofday简介

3 源码实现

3.1 参考代码

3.2 代码简介

3.3 代码测试

4 小小总结

5 更多分享

1 需求背景

在项目编程中,如果遇到调试代码性能的时候,慢慢需要加时戳来观察,找出那些耗时的操作。这种情况大部分需要人工干涉,如果我们需要程序自动帮忙完成耗时分析呢?我们可以怎么做呢?

本文就这个场景问题,提供一种解决方案,欢迎大家参考。

2 简要分析

2.1 算法分析

根据我们的常识,我们知道,要想知道一个操作的耗时,一般的做法就是在操作前取一个时间,然后操作后取一个时间;最后两个时间相减,得到的就是这段操作的耗时。

根据这里方法论,我们可以比较快地实现逻辑代码,但是我们应该用哪个函数取当前时间点呢?

2.2 gettimeofday简介

Linux C语言编程中,我们很容易会想到gettimeofday这个函数,下面我们将简单介绍一下这个函数。

参考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用于获取当前的时间是非常容易的,它会将时间结果存储在这个结构体中:

struct timeval {

** time_t tv_sec; /* seconds */

** suseconds_t tv_usec; /* microseconds / *

** };

struct timeval 结构体中有 tv_sec 秒参数 和 tv_usec 微妙参数,非常有利于我们做时间的加减计算。

下面我们就用这个函数来实现下本期的功能。

3 源码实现

3.1 参考代码

本例给出一个参考代码如下:

#include 
 #include 
 #include 
 #include static int get_cur_time_ms(void)
 {
     struct timeval tv;gettimeofday(&tv, NULL);  //使用gettimeofday获取当前系统时间return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval结构体将时间转换为ms
 }
 ​

3.2 代码简介

代码的功能逻辑,正如上面 的函数描述所说,正是利用gettimeofday返回的struct timeval结构内的成员变量,通过秒、毫秒、微妙的数量转换,将当前时间转换成毫秒,然后以函数返回值的形式输出。

值得注意的是,虽然gettimeofday在结构体定义上 【号称】有微妙级的精度,但是实际大部分的平台是没法达到这样的精度的,所以我们取其中,转换成毫秒级的精度,这个已经满足我们绝大多数应用场景了。

3.3 代码测试

针对上面的功能代码,写了一段小代码来测试下。

#include 
 #include 
 #include 
 #include 
 ​
 static int get_cur_time_ms(void)
 {
     struct timeval tv;
 ​
     gettimeofday(&tv, NULL);  //使用gettimeofday获取当前系统时间
 ​
     return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval结构体将时间转换为ms
 }
 ​
 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]);
     }  
 }
 ​
 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); //打印耗时
 ​
     return 0;
 }
 ​

以下测试代码的逻辑还是很简单的,主要就是测试获取 1024000个随机数的耗时情况。

image-20221205132449215

由于我本次测试使用的PC主机,其性能还是不错,所以测试出来的数据,还是耗时比较小的;如果这段代码放在嵌入式平台去运行的话,一个可能data数组的内存会爆,第二个耗时可能会大大增加。

感兴趣的朋友可以拿去一试。

注,本次测试的PC机情况如下:

image-20221205132334585

4 小小总结

  • 面对需求说明,尽快找到核心的功能要点,找到算法逻辑是关键;
  • 明白要做什么,再去选择合适的函数来满足功能逻辑,这是比较好的思路;
  • 考虑到gettimeofday的实际精度问题,牺牲部分不起眼的精度,依然可以满足大部分的需求。

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]、[华为云云享专家(嵌入式物联网架构设计师)]等荣誉。坚信【知识改变命运,技术改变世界】!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RT-Thread
    +关注

    关注

    31

    文章

    1303

    浏览量

    40288
收藏 人收藏

    评论

    相关推荐

    如何缩短Vivado的运行时间

    在Vivado Implementation阶段,有时是有必要分析一下什么原因导致运行时间(runtime)过长,从而找到一些方法来缩短运行时间
    的头像 发表于 05-29 14:37 1.4w次阅读
    如何缩短Vivado的<b class='flag-5'>运行时间</b>

    获取单片机运行时间

    的开始阶段使单片机的一个GPIO输出高电平,在待测程序段的结尾阶段再令这个GPIO输出低电平。用示波器通过检查高电平的时间长度,就知道了这段代码的运行时间。显然,借助于示波器的方法更为简便。 以下内容
    的头像 发表于 08-26 20:26 1890次阅读
    获取单片机<b class='flag-5'>运行时间</b>

    如何检查Linux服务器的运行时间

    Linux 中的 uptime 用于查看系统启动后的运行时间。它是一个比较简单的 Linux 命令,可以不带参数直接运行
    发表于 11-25 15:25 1.5w次阅读
    如何检查Linux服务器的<b class='flag-5'>运行时间</b>

    labview如何实时获取程序运行时间!!!!

    我们在做一个交通灯系统,(交通灯倒计时时间用做的数码管显示)当数码管显示3,2,1时,交通灯要亮黄灯,我做了一个条件语句,当时间在0~3之间时亮黄灯,否则其他灯亮。。但是不知道怎么获取程序运行
    发表于 12-26 00:30

    CCS 程序时间统计

    请教关于CCS 程序时间统计的问题: 能否指导simulator和emulator下各自测试代码运行时间的具体方法(程序实例或文档),所给的方法能客观地度量
    发表于 06-24 02:07

    LabVIEW程序运行时间与循环时间冲突

    的是:1,如何使循环读取的时间运行时间一致; 2,使用定时循环结构设定循环时间为什么不能达到循环时间运行时间一致。
    发表于 11-30 14:24

    C语言教程之显示程序运行时间

    C语言教程之显示程序运行时间,很好的C语言资料,快来学习吧。
    发表于 04-25 16:09 0次下载

    如何用SysTick实现测量程序运行时间

    在实际的项目开发过程中,常常遇到需要得到一段代码的运行时间,通常的方法是用示波器来测量,这篇博文将用 SysTick 来实现 精确测量 程序运行时间。 STM32F4 的内核定时
    的头像 发表于 05-09 14:07 6088次阅读
    如何用SysTick实现测量<b class='flag-5'>程序</b><b class='flag-5'>运行时间</b>

    电机运行时间进行排列 是分为两个部分来完成这个程序的设计的

    前几天有个学员咨询一个程序设计的问题,程序的控制要求如下:需要控制5台电机的运行,每台电机运行时需要记录运行时间,电机启动
    的头像 发表于 07-19 08:57 7245次阅读
    电机<b class='flag-5'>运行时间</b>进行排列 是分为两个部分来完成这个<b class='flag-5'>程序</b>的设计的

    如何高效测量ECU的运行时间

    ,最终可能会引起运行时间方面的问题。这在项目后期需要大量的时间和金钱来解决。如果不能掌握系统的运行状态,则很难发现系统内缺陷的根源。 解决方案 将TA软件工具套件与VX1000测量标定硬件相结合,可同步分析 ECU内部
    的头像 发表于 10-28 11:05 2274次阅读

    浅析STM32代码运行时间的技巧

    前言     测试代码的运行时间的两种方法: 使用单片机内部定时器,在待测程序段的开始启动定时器,在待测程序段的结尾关闭定时器。为了测量的准确性,要进行多次测量,并进行平均取值。 借助示波器的方法
    的头像 发表于 11-09 09:52 3941次阅读
    浅析STM32代码<b class='flag-5'>运行时间</b>的技巧

    ch32v307记录程序运行时间

    ch32v307记录程序运行时间程序开发中,很重要的一项任务就是对程序运行时间进行评估。对于大型的
    的头像 发表于 08-22 15:53 936次阅读

    西门子SCL编程50台电机运行时间累计方法

    当RUN信号为TRUE时,开始计时,FALSE时停止计时,单次运行时间清零,长按RESET5秒时,单次和总运行时间都清零。
    发表于 11-27 09:59 1998次阅读
    西门子SCL编程50台电机<b class='flag-5'>运行时间</b>累计方法

    jvm运行时内存区域划分

    JVM是Java Virtual Machine(Java虚拟机)的缩写,它是Java编程语言的运行环境。JVM的主要功能是将Java源代码转换为机器代码,并且在运行时管理Java程序的内存。JVM
    的头像 发表于 12-05 14:08 556次阅读

    三菱plc累计运行时间怎么编程

    具有重要意义。本文将详细介绍如何使用三菱PLC编程实现累计运行时间统计功能。 一、概述 累计运行时间是指设备或系统在一定时间内的总运行时间
    的头像 发表于 06-20 11:31 2448次阅读