鸿蒙轻内核M核源码分析系列五 时间管理
往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- 持续更新中……
在鸿蒙轻内核源码分析上一篇文章中,我们剖析了中断的源码,简单提到了Tick
中断。本文会继续分析Tick
和时间相关的源码,给读者介绍鸿蒙轻内核的时间管理模块。本文中所涉及的源码,以OpenHarmony LiteOS-M
内核为例,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。
时间管理模块以系统时钟为基础,可以分为2部分,一部分是SysTick
中断,为任务调度提供必要的时钟节拍;另外一部分是,给应用程序提供所有和时间有关的服务,如时间转换、统计功能。
系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”,也称为时标或者Tick
。Tick
是操作系统的基本时间单位,由用户配置的每秒Tick
数决定。如果用户配置每秒的Tick数目为1000,则1个Tick
等于1ms的时长。另外一个计时单位是Cycle
,这是系统最小的计时单位。Cycle
的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle
数,对于216 MHz
的CPU
,1秒产生216000000个cycles
。
用户以秒、毫秒为单位计时,而操作系统以Tick
为单位计时,当用户需要对系统进行操作时,例如任务挂起、延时等,此时可以使用时间管理模块对Tick
和秒/毫秒进行转换。
下面,我们剖析下时间管理模块的源代码,若涉及开发板部分,以开发板工程targets\cortex-m7_nucleo_f767zi_gcc\
为例进行源码分析。
1、时间管理初始化和启动
我们先看下时间管理模块的相关配置,然后再剖析如何初始化,如何启动。
1.1 时间管理相关的配置
时间管理模块涉及3个配置项,系统时钟OS_SYS_CLOCK
、每秒Tick
数目LOSCFG_BASE_CORE_TICK_PER_SECOND
两个配置选项,还有宏LOSCFG_BASE_CORE_TICK_HW_TIME
。LOSCFG_BASE_CORE_TICK_HW_TIME
默认关闭,开启时,需要提供定制函数VOID platform_tick_handler(VOID)
,在Tick中断处理函数中执行定制操作。这些配置项在模板开发板工程目录的文件target_config.h
中定义,如文件targets\cortex-m7_nucleo_f767zi_gcc\target_config.h
中定义如下:
#define OS_SYS_CLOCK 96000000
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
1.2 时间管理初始化和启动
函数INT32 main(VOID)
会调用kernel\src\los_init.c
中的函数UINT32 LOS_Start(VOID)
启动系统,该函数会调用启动调度函数UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
。源码如下:
LITE_OS_SEC_TEXT_INIT UINT32 LOS_Start(VOID)
{return HalStartSchedule(OsTickHandler);
}
函数UINT32 HalTickStart(OS_TICK_HANDLER *handler)
定义在kernel\arch\arm\cortex-m7\gcc\los_context.c
,源码如下。其中函数参数为Tick
中断处理函数OsTickHandler()
,后文会分析该tick
中断处理函数。⑴处代码继续调用函数进一步调用函数HalTickStart(handler)
来设置Tick
中断启动。⑵处会调用汇编函数HalStartToRun
开始运行系统,后续任务调度系列再详细分析该汇编函数。
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
{UINT32 ret;
⑴ ret = HalTickStart(handler);if (ret != LOS_OK) {return ret;}
⑵ HalStartToRun();return LOS_OK; /* never return */
}
函数HalTickStart(handler)
定义在文件kernel\arch\arm\cortex-m7\gcc\los_timer.c
,源码如下,我们分析下函数的代码实现。⑴处校验下时间管理模块的配置项的合法性。在开启宏LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT
时,会使用系统定义的中断。会执行⑵处的代码,调用定义在文件kernel\arch\arm\cortex-m7\gcc\los_interrupt.c
中的函数OsSetVector()
设置中断向量,该函数在中断系列会详细分析。⑶处设置全局变量g_sysClock
为系统时钟,g_cyclesPerTick
为每tick
对应的cycle
数目,g_ullTickCount
初始化为0,表示系统tick
中断发生次数。⑷处调用定义在targets\cortex-m7_nucleo_f767zi_gcc\Drivers\CMSIS\Include\core_cm7.h
文件中的内联函数uint32_t SysTick_Config(uint32_t ticks)
,初始化、启动系统定时器Systick
和中断。
WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler)
{UINT32 ret;⑴ if ((OS_SYS_CLOCK == 0) ||(LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) ||(LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) {return LOS_ERRNO_TICK_CFG_INVALID;}#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1)
#if (OS_HWI_WITH_ARG == 1)OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler, NULL);
#else
⑵ OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler);
#endif
#endif⑶ g_sysClock = OS_SYS_CLOCK;g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND;g_ullTickCount = 0;⑷ ret = SysTick_Config(g_cyclesPerTick);if (ret == 1) {return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL;}return LOS_OK;
}
1.3 Tick中断处理函数OsTickHandler()
文件kernel\src\los_tick.c
定义的函数VOID OsTickHandler(VOID)
,是时间管理模块中执行最频繁的函数,每当Tick
中断发生时就会调用该函数。我们分析下该函数的源码,⑴处如果开启宏LOSCFG_BASE_CORE_TICK_HW_TIME
,会调用定制的tick
处理函数platform_tick_handler()
,默认不开启。⑵处会更新全局变量g_ullTickCount
,⑶处如果开启宏LOSCFG_BASE_CORE_TIMESLICE
,会检查当前运行任务的时间片,在后续任务模块会详细分析下函数OsTimesliceCheck()
。⑷处会遍历任务的排序链表,检查是否有超时的任务。⑸处如果支持定时器特性,会检查定时器是否超时。
源码如下:
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
{
#if (LOSCFG_BASE_CORE_TICK_HW_TIME == 1)
⑴ platform_tick_handler();
#endif⑵ g_ullTickCount++;#if (LOSCFG_BASE_CORE_TIMESLICE == 1)
⑶ OsTimesliceCheck();
#endif⑷ OsTaskScan(); // task timeout scan#if (LOSCFG_BASE_CORE_SWTMR == 1)
⑸ (VOID)OsSwtmrScan();
#endif
}
2、LiteOS
内核时间管理常用操作
时间管理提供下面几种功能,时间转换、时间统计等,这些函数定义在文件kernel\src\los_tick.c
,我们剖析下这些操作的源代码实现。
2.1 时间转换操作
2.1.1 毫秒转换成Tick
函数UINT32 LOS_MS2Tick(UINT32 millisec)
把输入参数毫秒数UINT32 millisec
可以转化为Tick
数目。代码中OS_SYS_MS_PER_SECOND
,即1秒等于1000毫秒。时间转换也比较简单,知道一秒多少Tick
,除以OS_SYS_MS_PER_SECOND
,得出1毫秒多少Tick
,然后乘以millisec
,计算出Tick
数目的结果值并返回。
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
{if (millisec == OS_NULL_INT) {return OS_NULL_INT;}return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND;
}
2.1.2 Tick转化为毫秒
函数UINT32 LOS_Tick2MS(UINT32 tick)
把输入参数Tick
数目转换为毫秒数。时间转换也比较简单,ticks
数目除以每秒多少Tick
数值LOSCFG_BASE_CORE_TICK_PER_SECOND
,计算出多少秒,然后转换成毫秒,计算出结果值并返回。
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 ticks)
{return ((UINT64)ticks * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
}
2.1.3 Cycle数目转化为毫秒
介绍转换函数之前,先看下一个CpuTick
结构体,结构体比较简单,就2个成员,分别表示一个UINT64
类型数据的高、低32位数值。
typedef struct tagCpuTick {UINT32 cntHi; /* < 一个64位数值的高32位 */UINT32 cntLo; /* < 一个64位数值的低32位 */
} CpuTick;
继续看转换函数OsCpuTick2MS()
,它可以把CpuTick
类型表示的cycle
数目转换为对应的毫秒数,输出毫秒数据的高、低32位数值。看下具体的代码,⑴处校验参数是否为空指针,⑵处检查系统时钟是否配置。⑶处把CpuTick
结构体表示的cycle
数目转化为UINT64
类型数据。⑷处进行数值计算,(DOUBLE)g_sysClock / OS_SYS_MS_PER_SECOND
得到每毫秒多少个cycle
数,然后和tmpCpuTick
做除法运算,得到cycle
数目对应的毫秒数目。⑸处把DOUBLE
类型转换为UINT64
类型,然后执行⑹,分别把结果数值的高、低64位赋值给*msLo
、*msHi
。
LITE_OS_SEC_TEXT_INIT UINT32 OsCpuTick2MS(CpuTick *cpuTick, UINT32 *msHi, UINT32 *msLo)
{UINT64 tmpCpuTick;DOUBLE temp;⑴ if ((cpuTick == NULL) || (msHi == NULL) || (msLo == NULL)) {return LOS_ERRNO_SYS_PTR_NULL;}⑵ if (g_sysClock == 0) {return LOS_ERRNO_SYS_CLOCK_INVALID;}
⑶ tmpCpuTick = ((UINT64)cpuTick->cntHi << OS_SYS_MV_32_BIT) | cpuTick->cntLo;
⑷ temp = tmpCpuTick / ((DOUBLE)g_sysClock / OS_SYS_MS_PER_SECOND);tmpCpuTick = (UINT64)temp;*msLo = (UINT32)tmpCpuTick;*msHi = (UINT32)(tmpCpuTick >> OS_SYS_MV_32_BIT);return LOS_OK;
}
2.1.4 Cycle数目转化为微秒
转换函数OsCpuTick2US()
,它可以把CpuTick
类型表示的cycle
数目转换为对应的毫秒数,输出毫秒数据的高、低32位数值。该函数和OsCpuTick2MS()
类似,自行阅读即可。
LITE_OS_SEC_TEXT_INIT UINT32 OsCpuTick2US(CpuTick *cpuTick, UINT32 *usHi, UINT32 *usLo)
{UINT64 tmpCpuTick;DOUBLE temp;if ((cpuTick == NULL) || (usHi == NULL) || (usLo == NULL)) {return LOS_ERRNO_SYS_PTR_NULL;}if (g_sysClock == 0) {return LOS_ERRNO_SYS_CLOCK_INVALID;}tmpCpuTick = ((UINT64)cpuTick->cntHi << OS_SYS_MV_32_BIT) | cpuTick->cntLo;temp = tmpCpuTick / ((DOUBLE)g_sysClock / OS_SYS_US_PER_SECOND);tmpCpuTick = (UINT64)temp;*usLo = (UINT32)tmpCpuTick;*usHi = (UINT32)(tmpCpuTick >> OS_SYS_MV_32_BIT);return LOS_OK;
}
2.2 时间统计操作
2.2.1 获取每个Tick等于多少Cycle数
函数UINT32 LOS_CyclePerTickGet(VOID)
计算1个tick
等于多少cycle
。g_sysClock
系统时钟表示1秒多少cycle
,LOSCFG_BASE_CORE_TICK_PER_SECOND
一秒多少tick
,相除计算出1 tick
多少cycle
数,即g_cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND
。
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID)
{return g_cyclesPerTick;
}
2.2.2 获取自系统启动以来的Tick数
UINT64 LOS_TickCountGet(VOID)
函数计算自系统启动以来的Tick
中断的次数。需要注意,在关中断的情况下不进行计数,不能作为准确时间使用。每次Tick
中断发生时,在函数VOID OsTickHandler(VOID)
中会更新g_ullTickCount
数据。
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
{return g_ullTickCount;
}
2.2.3 获取系统时钟
UINT32 LOS_SysClockGet(VOID)
函数获取配置的系统时钟。
UINT32 LOS_SysClockGet(VOID)
{return g_sysClock;
}
2.2.4 获取系统启动以来的Cycle数
函数VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo)
定义在文件kernel\arch\arm\cortex-m7\gcc\los_timer.c
中,该函数获取系统启动以来的Cycle
数。返回结果按高、低32位的无符号数值UINT32 *cntHi, UINT32 *cntLo
分别返回。
我们看下该函数的源码。先关中断,然后⑴处获取启动启动以来的Tick
数目。⑵处通过读取当前值寄存器SysTick Current Value Register
,获取hwCycle
。⑶处表示中断控制和状态寄存器Interrupt Control and State Register
的第TICK_CHECK
位为1时,表示挂起systick
中断,tick
没有计数,需要加1校准。⑷处根据swTick
、g_cyclesPerTick
和hwCycle
计算出自系统启动以来的Cycle
数。⑸处获取Cycle
数的高、低32位的无符号数值,然后开中断、返回。
LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo)
{UINT64 swTick;UINT64 cycle;UINT32 hwCycle;UINTPTR intSave;intSave = LOS_IntLock();⑴ swTick = g_ullTickCount;
⑵ hwCycle = SysTick->VAL;⑶ if ((SCB->ICSR & TICK_CHECK) != 0) {hwCycle = SysTick->VAL;swTick++;}⑷ cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle));⑸ *cntHi = cycle >> SHIFT_32_BIT;*cntLo = cycle & CYCLE_CHECK;LOS_IntRestore(intSave);return;
}
小结
本文带领大家一起剖析了鸿蒙轻内核的时间管理模块的源代码。时间管理模块为任务调度提供必要的时钟节拍,会向应用程序提供所有和时间有关的服务,如时间转换、统计、延迟功能。后续也会陆续推出更多的分享文章,敬请期待,也欢迎大家分享学习、使用鸿蒙轻内核的心得,有任何问题、建议,都可以留言给我们: https://gitee.com/openharmony/kernel_liteos_m/issues 。为了更容易找到鸿蒙轻内核代码仓,建议访问 https://gitee.com/openharmony/kernel_liteos_m,关注Watch
、点赞Star
、并Fork
到自己账户下,谢谢。
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
相关文章:

鸿蒙轻内核M核源码分析系列五 时间管理
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 持续更新中…… 在鸿蒙轻内核源码分析上一篇文章中,我们剖析了中断的源码,简单提到了Tick中断。本文会继续分析Tick和时间相关的源…...
Python Opencv鼠标回调
使用 OpenCV 的 cv2.setMouseCallback() 方法来捕捉鼠标事件,并实现以下功能: 实时在鼠标指针附近显示其位置的像素坐标。通过左键双击,将像素坐标记录到数组中。通过右键点击,取消上一次添加的坐标。 下面是实现代码的示例&…...

Ubuntu环境的MySql下载安装
下载压缩包 此文章下载的mysql版本位5.7.29 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar解压缩 sudo tar -xvf mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar命令解释 -x:…...

Android系统去掉WIFI模块
先说应用场景,有些特定设备,不能连接wifi。需要隐藏的模块,QS面板模块的wifi,还有设置里面的wifi.由于QS属于SystemUI,熟悉SystemUI之后,就可以直接去SystemUi那里找,找到QSTitle 默认配置的地方。 一、…...
代码随想录 -- 二叉树 -- 翻转二叉树
226. 翻转二叉树 - 力扣(LeetCode) 递归比较简单 class Solution(object):def invertTree(self, root):if rootNone:returnnode rootif node.left or node.right:tempnode.leftnode.leftnode.rightnode.righttempself.invertTree(node.left)self.inve…...
Node.js之文件复制
1.方式一:readFile // 导入fs模块 const fs require("fs") // 导入process模块 const process require("process")// 读取文件内容 let data fs.writeFileSync(./test.txt) // 写入文件内容 fs.writeFileSync(./test1.txt, data) 2.方式二&…...

新手c语言讲解及题目分享(十六)--文件系统专项练习
在我刚开始学习c语言的时候就跳过了这一章节,但在后面慢慢发现这一章节还是比较重要的,如果你报考了计算机二级c语言的话,你应该可以看到后面的三个大题有时会涉及到这章。所以说这章还是非常重要的。 目录 前言 一.打开文件 1.Fopen( )函数返回值 2&…...

RabbitMQ本地Ubuntu系统环境部署与无公网IP远程连接服务端实战演示
文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 安装内网穿透工具3.1 安装cpolar内网穿透3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站&am…...

[C++#28][多态] 两个条件 | 虚函数表 | 抽象类 | override 和 final | 重载 重写 重定义
目录 0.引入 1.虚函数 1. 虚函数的重写/覆盖 2. 特例1:不加 virtual 关键字的重写 3. 特例2:协变(了解) 2.多态的构成和细节 1. C11 的 override 和 final 1. final 不可重写 2. override 报错检查 ⭕2. 重载、覆盖&…...
List 集合指定值升序降序排列Comparator实现
升序排序 升序排序通常是指从小到大的排序。对于数值类型来说,可以直接使用 compareTo 方法,而对于其他类型,可以根据实际需求实现比较逻辑。 示例代码 import java.util.Comparator; import java.util.List; import java.util.ArrayList;cl…...

【Day07】
目录 MySQL-DQL- 基本查询 MySQL-DQL- 条件查询 MySQL-DQL- 聚合函数 MySQL-DQL- 分组查询 MySQL-DQL- 排序查询 MySQL-DQL- 分页查询 MySQL-DQL- 案例 MySQL-多表设计-一对多 MySQL-多表设计-一对多-外键约束 MySQL-多表设计-一对一&多对多 MySQL-多表设计-案例…...

shell 控制台显示彩色文字的方法
在shell脚本中,如果我们希望在控制台能显示带颜色的文字, 那就需要使用shell中的色彩专用变量代码来进行. shell中的各种颜色代码定义 # 颜色定义 BLACK"\033[0;30m" DARK_GRAY"\033[1;30m" BLUE"\033[0;34m" LIGHT_BLUE"\033[1;3…...

Nginx: 缓存, 不缓存特定内容和缓存失效降低上游压力策略及其配置示例
概述 在负载均衡的过程中,有一个比较重要的概念,就是缓存利用缓存可以很好协调Nginx在客户端和上游服务器之间的速度不匹配的矛盾从而很好的解决整体系统的响应速度 如果用户需要通过Nginx获取某一些内容的时候,发起一个request请求这个请求…...
Python 全栈系列266 Kafka服务的Docker搭建
说明 在大量数据处理任务下的缓存与分发 这个算是来自顾同学的助攻1,我有点java绝缘体的体质,碰到和java相关的安装部署总会碰到点奇怪的问题,不过现在已经搞定了。测试也接近了kafka官方标称的性能。考虑到网络、消息的大小等因素࿰…...

集合框架,List常用API,栈和队列初识
回顾 集合框架 两个重点——ArrayList和HashSet. Vector/ArraysList/LinkedList区别 VectorArraysListLinkedList底层实现数组数组链表线程安全安全不安全不安全增删效率较低较低高扩容*2*1.5-------- (>>)运算级最低,记得加括号。 常…...

构建全景式智慧文旅生态:EasyCVR视频汇聚平台与AR/VR技术的深度融合实践
在科技日新月异的今天,AR(增强现实)和VR(虚拟现实)技术正以前所未有的速度改变着我们的生活方式和工作模式。而EasyCVR视频汇聚平台,作为一款基于云-边-端一体化架构的视频融合AI智能分析平台,可…...
C++结构体声明时初始化
提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问: 本文目标: 一、背景 最近 二、 2.1 c 结构体默认初始化 在C中,结构体的默认成员初始化可以通过构造函数来完成。如果没有为结构体提供构造函数&#x…...

基于微信的热门景点推荐小程序的设计与实现(论文+源码)_kaic
摘 要 近些年来互联网迅速发展人们生活水平也稳步提升,人们也越来越热衷于旅游来提高生活品质。互联网的应用与发展也使得人们获取旅游信息的方法也更加丰富,以前的景点推荐系统现在已经不足以满足用户的要求了,也不能满足不同用户自身的个…...
9、设计模式
设计模式 1、工厂模式 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时&…...

数学专题.
数论 1.判断质数 定义:在大于1的整数中,如果只包含1和本身这两个约数,就称为质数or素数 Acwing 866.试除法判断质数 2.预处理质数(筛质数) Acwing 868.筛质数 3.质因数分解 Acwing 867.分解质因数 4.阶乘分解 5.因…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
【Ftrace 专栏】Ftrace 参考博文
ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...