Porting x86架构的rdtsc函数到ARM64架构的方法

极术社区 2021-07-08 18:21:32

首发极术社区,作者James 张

x86架构下,我们要想在用户态通过定时器方式来对代码执行时间做衡量可以使用Time Stamp Counter(TSC)寄存器,可精确到CPU Cycle级别。

由于ARM架构支持的是完全不同的指令集,因此获取TSC的方法存在差异。近些年来随着arm架构的广泛使用,以前基于x86架构运行的应用,现在要跑在ARM架构下,当运行的应用需要获取TSC时,则需要汇编级的代码移植,这对上层应用编写者提出了不小的挑战。为此,本文分享Arm64架构下如何获取TSC的方法,以方便大家移植使用。

首先,我们介绍一种利用Arm64架构的System counter来实现提供TSC的方法。System counter是Arm64下独立于CPU core的计数器,在系统上电时,会给此计数器设置固定的频率。一个映射system counter计数器内容的寄存器为CNTVCT_EL0,可在用户态下读取此寄存器获取counter值。而CNTFRQ_EL0保存的是counter的频率值。

以c/c++语言为例给出实现代码:

static inline uint64_t 
arm64_cntvct(void)
{
   uint64_t tsc;
   asm volatile("mrs %0, cntvct_el0" : "=r" (tsc));
   return tsc;
}

static inline uint64_t
arm64_cntfrq(void)
{
   uint64_t freq;
   asm volatile("mrs %0, cntfrq_el0" : "=r" (freq));
   return freq;
}

static inline uint64_t
rdtsc(void)
{
   return arm64_cntvct();
}

通过以上函数实现获取counter值及频率值,我们是可以实现对某些任务做相应的时间衡量的。但是system counter的精度一般不会超过100MHz,一般是达不到CPU cycle级别的精度。

考虑到利用system counter来实现提供TSC的方法可能满足不了某些任务的需求,我们给出方法二来实现提供TSC并能达到CPU cycle级别的精度要求。此方法是借助PMU系列寄存器中的PMCCNTR_EL0,读取此寄存器就可以知道当前CPU已运行了多少 cycle。
以c/c++语言为例给出实现代码:

static inline uint64_t
arm64_pmccntr(void)
{
   uint64_t tsc;
   asm volatile("mrs %0, pmccntr_el0" : "=r"(tsc));
   return tsc;
}

static inline uint64_t
rdtsc(void)
{
   return arm64_pmccntr();
}

通过以上函数实现,我们获取的TSC可以达到CPU cycle级别的精度。但是Linux系统下,用户态默认没有开启对PMCCNTR_EL0寄存器的读权限,需要通过内核态使能后才能读取。

以c/c++语言为例给出核心使能代码:

static void enable_pmu_pmccntr(void)
{
   u64 val = 0;
   asm volatile("msr pmintenset_el1, %0" : : "r" ((u64)(0 << 31)));
   asm volatile("msr pmcntenset_el0, %0" :: "r" ((u64)(1 << 31)));
   asm volatile("msr pmuserenr_el0, %0" : : "r"((u64)(1 << 0) | (u64)(1 << 2)));
   asm volatile("mrs %0, pmcr_el0" : "=r" (val));
   val |= ((u64)(1 << 0) | (u64)(1 << 2));
   isb();
   asm volatile("msr pmcr_el0, %0" : : "r" (val));
}

详细使能步骤可参考如下链接:
[https://ilinuxkernel.com/?p=1755]

...全文
4817 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
CSDN-Ada助手 2023-01-13
  • 打赏
  • 举报
回复
您可以前往 CSDN问答-编程语言 发布问题, 以便更快地解决您的疑问
[深入理解计算机系统(原书第2版)].(美)布莱恩特,奥哈拉伦.扫描版.pdf part1 http://download.csdn.net/detail/zhanglu231123/4555359 深入理解Android 卷I 扫描完整版 http://www.eoeandroid.com/thread-199577-1-1.html 深入Linux内核架构-高清扫描中文版-1055页-108M http://www.eoeandroid.com/thread-198472-1-1.html 精通LINUX设备驱动程序开发中文扫描版36M http://www.eoeandroid.com/thread-198291-1-1.html 精通Android游戏开发中文扫描版完整版40M http://www.eoeandroid.com/thread-197513-1-1.html A8-Android模块驱动开发400页60M (Driver & HAL & JNI) 有图有真相 包括传感器 摄像头驱动全套开发 http://www.eoeandroid.com/thread-196680-1-1.html 深入理解Android 高清完整版34M 邓凡平 http://www.eoeandroid.com/thread-196526-1-1.html Android-3D游戏开发技术详解与典型案例--149M高清版 http://www.eoeandroid.com/thread-194855-1-1.html 深入理解LINUX网络技术内幕--124M扫描版 http://www.eoeandroid.com/thread-194804-1-1.html 赵炯Linux内核剖析-0.12扫描版198M LINUX内核完全剖析:基于0.12内核.pdf http://www.eoeandroid.com/thread-188911-1-1.html Android系统级深入开发—移植与调试--385页64M http://www.eoeandroid.com/thread-173632-1-1.html Linux-内核设计的艺术-42M-高清完整版-201107 http://www.eoeandroid.com/thread-171027-1-1.html 任桥伟的 Linux内核图书扫描版200M http://www.eoeandroid.com/thread-174139-1-1.html 华清远见Android移植班讲义 170页 很好很强大 很详细 http://www.eoeandroid.com/thread-166957-1-1.html 杨丰盛-Android技术内幕-高清完整版50M http://www.eoeandroid.com/thread-160117-1-1.html 李刚-疯狂Android讲义 --237M-高清扫描版-带书签目录 http://www.eoeandroid.com/thread-192150-1-1.html 精通Android3中文版87M高清完整版 http://www.eoeandroid.com/thread-194155-1-1.html Android -ICS 全套驱动移植30页(wlan bluetootsh audio display mmc touchscreen keypad nand usb modem porting )

30,588

社区成员

发帖
与我相关
我的任务
社区描述
欢迎加入极术社区,共创中国智能计算生态。社区提供智能计算领域的资讯,鼓励技术写作和问答互助,致力促进中国芯片技术的合作创新。地址:https://aijishu.com
人工智能 企业社区
社区管理员
  • 极术社区
  • 闫辉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧