当前位置: 首页 > news >正文

prfm命令初探

1. 前言

        在查看一段neon代码时,发现有如下片段,为使用汇编进行数据预取操作。这是一个新的知识点,记录一下学习过程。

  __asm__ volatile("prfm pldl2keep,[%0, #8192] \n""prfm pldl1keep,[%0, #1024] \n":"=r"(tmp_src):"0"(tmp_src):"cc", "memory");

2. GCC内联汇编

        GCC中的内联汇编格式如下

__asm__ __volatile__(指令部: 输出部: 输入部: 副作用列表)

        其中的知识点列出如下:

1)__asm__/asm是GCC中的一个关键字,用来声明一个内联汇编表达式。

2)__volatile__/volatile是GCC中的一个关键字,告诉编译器不允许对后面嵌入的代码进行优化。

3)指令部中带有%的数字如%0、%1等,表示需要使用寄存器的操作数

4)输出部:用于描述在指令部中可以修改的C语言变量和它的约束条件。一般以"="/"+"开头,"="表示操作数可写,"+"表示可读可写;然后是一个字母,表示对操作数类型的说明。

5)输入部:描述指令部中智能读取的C语言变量以及约束条件。输入部中的参数只有只读属性,所以不能使用"="/"+"进行修饰。

6)副作用列表:一般以“memory”结束。“cc”表示内嵌代码修改了状态寄存器的相关标志位;“memory”告诉编译器内嵌代码改变了内存状态

        看一个例子,代码如下,实现将寄存器中的数据读取出来。

<arch/arm64/include/asm/irqflags.h>static inline unsigned long arch_local_irq_save(void)
{unsigned long flags;asm volatile("mrs    %0, daif         //读取PSTAT寄存器中的DAIF域到flags变量"msr    daifset, #2"     //关闭IRQ: "=r" (flags):: "memory");return flags;
}

        输出部中%0对应"=r" (flags),“=”表示操作数具备可写属性,“r”表示使用一个通用寄存器;输入部为空;副作用列表表示代码改变了内存状态。

3. prfm指令

        prfm是ARM中的一个汇编指令,用于执行预取操作,旨在减少未来的缓存缺失延迟。通过预先加载数据到缓存中,可以在后续访问这些数据时更快地获取它们,从而提高程序的整体性能。

1)命令基本形式

        prfm命令的基本形式如下

prfm <type>, <address>

        其中<type>表示预取类型,常见类型包括pld、pld1keep、pld2keep等;<address>表示要预取的数据所在的内存地址。

2)预取类型

  • pld;将数据预取到最后一级缓存(L1或L2),数据块大小一般为64字节。
  • pldl1keep;将数据预取到L1数据缓存,数据块大小一般为64字节。
  • pldl2keep;将数据预取到L2数据缓存,数据块大小一般为64字节。

        由于涉及到内存操作,有必要在执行预取之前确保地址有效,这也算是一种防御性编程。

4. 小结

        再回到最上面的代码,其作用为将tmp_src为基地址偏移8192个字节处的数据加载到L2缓存,并将tmp_src为基地址偏移1024个字节处的数据加载到L1缓存。": "=r"(srcdata_p)":表示 srcdata_p 可以存储在任意类型的寄存器中,并且会被更新;:"0"(srcdata_p)":表示使用与输出约束相同的寄存器编号,即 srcdata_p

5. 参考

https://zhuanlan.zhihu.com/p/465498325

https://www.cnblogs.com/FireLife-Cheng/p/18186919

http://www.lryc.cn/news/436958.html

相关文章:

  • AI大模型需要学什么?怎么学?从零基础入门大模型(保姆级),从这开始出发!
  • python自述3
  • Redis常见的数据结构
  • 批量插入insert到SQLServer数据库,BigDecimal精度丢失解决办法,不动代码,从驱动层面解决
  • 随手记:uniapp小程序登录方式和小程序使用验证码登录
  • 【Hadoop|HDFS篇】DataNode概述
  • Vue2 VueRouter学习笔记
  • 3D培训大师,化工企业安全教育与应急演练的新助力
  • 斯坦福大学论文润色chat-gpt指令
  • 简单硬件在环搭建(ROS+Prescan+Carsim+simulink)
  • 【Python 数据分析学习】Pandas基础与应用(1)
  • pytorch入门(1)——pytorch加载数据初认识
  • Spring下载文件
  • 如何在数据库中备份表:操作指南与注意事项
  • 【数据结构】第八节:链式二叉树
  • Fair Graph RepresentationLearning via Diverse Mixture-of-Experts
  • 电机驱动开发之驱动板
  • STM32F1 HAL库笔记2_HAL 系统驱动程序
  • el-table实现当内容过多时,el-table显示滚动条,页面不显示滚动条
  • Java面试篇基础部分-Java中的异常以及异常处理
  • win11 MySQL的坑
  • stm32单片机个人学习笔记1(简单介绍)
  • python中@staticmethod、@classmethod用法
  • Harmony Next 文件命令操作(发送、读取、媒体文件查询)
  • Go语言中的链表与双向链表实现
  • 开始一个WPF项目时的记忆重载入
  • 用go语言实现树和哈希表算法
  • 基于SpringBoot+Vue+MySQL的校园健康驿站管理系统
  • 深入理解MATLAB中的事件处理机制
  • 线程--线程同步