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

MSI_MSI-X中断之源码分析

MSI_MSI-X中断之源码分析


文章目录

  • MSI_MSI-X中断之源码分析
    • 一、 怎么发出MSI/MSI-X中断
      • 1.1 在RK3399上体验
        • 1.1.1 安装工具
        • 1.1.2 查看设备MSI-X信息
        • 1.1.3 验证MSI-X信息
    • 二、 怎么使用MSI/MSI-X
    • 三、 MSI/MSI-X中断源码分析
      • 3.1 IRQ Domain创建流程
        • 3.1.1 GIC
        • 3.1.2 ITS
        • 3.1.3 PCI MSI
        • 3.1.4 PCIe控制器
      • 3.2 分配中断
  • 致谢



开发板资料:

  • 开发板Firefly-rk3399资料

参考内核文件:

  • Documentation\PCI\MSI-HOWTO.txt
  • drivers\pci\host\pcie-rockchip.c
  • drivers\nvme\host\pci.c
  • drivers\irqchip\irq-gic-v3.c
  • drivers\irqchip\irq-gic-v3-its.c
  • drivers\irqchip\irq-gic-v3-its-pci-msi.c

一、 怎么发出MSI/MSI-X中断

PCIe设备向发出中断,它发出TLP包,往某个地址写入某个数据即可:

  • 往哪个地址?GICv3 ITS的GITS_TRANSLATER寄存器,TLP包里使用的是PCI地址
  • 写什么数据?0、1、2、……,要发出第1个中断时写0,要发出第2个中断时写1,……

在设备树文件rk3399.dtsi中,可以看到ITS的基地址是0xfee20000:

its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};

IHI0069G_gic_architecture_specification.pdf中有ITS寄存器的偏移地址:

在这里插入图片描述
GITS_TRANSLATER寄存器的CPU地址是:0xfee20000 + 0x010000 + 0x0040 = 0xfee30040。

对应的PCI地址也是0xfee30040(驱动程序里为例方便,故意使得CPU地址跟PCI地址相同,这2个地址属于不同地址空间),

所以下图中PCI地址都是0xfee30040。

在这里插入图片描述

1.1 在RK3399上体验

在RK3399开发板,插上了NVMe SSD固态硬盘。

在这里插入图片描述

1.1.1 安装工具

请给RK3399刷入Ubuntu映像文件,然后在开发板上执行:

udhcpc  # 获取IP
apt update  # 更新源
apt install pciutils  # 安装lspci工具
apt install devmem2   # 安装devmem2工具

1.1.2 查看设备MSI-X信息

执行lspci -vvv,得到如下信息:

01:00.0 Non-Volatile memory controller: Silicon Motion, Inc. Device 2263 (rev 03) (prog-if 02 [NVM Express])Subsystem: Silicon Motion, Inc. Device 2263Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-Latency: 0Interrupt: pin A routed to IRQ 231Region 0: Memory at fa000000 (64-bit, non-prefetchable) [size=16K]Capabilities: [40] Power Management version 3Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-Capabilities: [50] MSI: Enable- Count=1/8 Maskable+ 64bit+Address: 0000000000000000  Data: 0000Masking: 00000000  Pending: 00000000Capabilities: [70] Express (v2) Endpoint, MSI 00DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimitedExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0.000WDevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop- FLReset-MaxPayload 128 bytes, MaxReadReq 512 bytesDevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L0s <1us, L1 <8usClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+, OBFF Not SupportedDevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF DisabledLnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-Compliance De-emphasis: -6dBLnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-, EqualizationPhase1-EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-Capabilities: [b0] MSI-X: Enable+ Count=16 Masked-Vector table: BAR=0 offset=00002000PBA: BAR=0 offset=00002100Capabilities: [100 v2] Advanced Error ReportingUESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-Capabilities: [158 v1] #19Capabilities: [178 v1] Latency Tolerance ReportingMax snoop latency: 0nsMax no snoop latency: 0nsCapabilities: [180 v1] L1 PM SubstatesL1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+PortCommonModeRestoreTime=10us PortTPowerOnTime=10usL1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-T_CommonMode=0us LTR1.2_Threshold=0nsL1SubCtl2: T_PwrOn=10usKernel driver in use: nvme

从上述信息可以看到:

        Region 0: Memory at fa000000 (64-bit, non-prefetchable) [size=16K]Capabilities: [b0] MSI-X: Enable+ Count=16 Masked-Vector table: BAR=0 offset=00002000PBA: BAR=0 offset=00002100

这表示:

  • MSI-X: Enable+:使用MSI-X功能
  • Vector table: BAR=0 offset=00002000:MSI的向量在BAR 0偏移地址0x00002000处
  • Region 0: Memory at fa000000:
    • BAR 0的PCI地址是0xfa000000,
    • 驱动程序里为了方便令CPU地址等于PCI地址,所以BAR的CPU地址也是0xfa000000。

我们可以去读取 0xfa000000 + 0x00002000开始的向量表,验证里:

  • msg addr为0xfee30040
  • msg data为0、1、……
    在这里插入图片描述

1.1.3 验证MSI-X信息

在这里插入图片描述

二、 怎么使用MSI/MSI-X

参考内核文档:Documentation\PCI\MSI-HOWTO.txtdrivers\nvme\host\pci.c

主要函数是这2个:

int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,int minvec, int maxvec);
int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec);

示例代码如下:

	// 分配 msix_entry 数组,每一数组项用来保存一个中断的信息dev->entry = kzalloc_node(num_possible_cpus() * sizeof(*dev->entry),GFP_KERNEL, node);// 先尝试使用MSI-Xvecs = pci_enable_msix_range(pdev, dev->entry, 1, nr_io_queues);if (vecs < 0) {// 再尝试使用MSIvecs = pci_enable_msi_range(pdev, 1, min(nr_io_queues, 32));if (vecs < 0) {vecs = 1;} else {for (i = 0; i < vecs; i++)dev->entry[i].vector = i + pdev->irq;}}// request_irq: 中断号都保存在dev->entry[i].vector里for (i = 0; i < vecs; i++)request_irq(dev->entry[i].vector, ...);

注意,在pci_enable_msix_range或者pci_enable_msi_range函数中:

  • minvec从1开始
  • 对于pci_enable_msix_range,中断号保存在entries[i].vector里
  • 对于pci_enable_msi_range,第1个中断号保存在pdev->irq里

三、 MSI/MSI-X中断源码分析

3.1 IRQ Domain创建流程

从PCI设备触发,涉及三个IRQ Domain:

  • drivers\irqchip\irq-gic-v3-its-pci-msi.c
  • drivers\irqchip\irq-gic-v3-its.c
  • drivers\irqchip\irq-gic-v3.c

3.1.1 GIC

设备树:

        gic: interrupt-controller@fee00000 {compatible = "arm,gic-v3";#interrupt-cells = <4>;#address-cells = <2>;#size-cells = <2>;ranges;interrupt-controller;reg = <0x0 0xfee00000 0 0x10000>, /* GICD */<0x0 0xfef00000 0 0xc0000>, /* GICR */<0x0 0xfff00000 0 0x10000>, /* GICC */<0x0 0xfff10000 0 0x10000>, /* GICH */<0x0 0xfff20000 0 0x10000>; /* GICV */interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};

驱动代码:`drivers\irqchip\irq-gic-v3.c

在这里插入图片描述

3.1.2 ITS

设备树:

its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};

驱动代码:`drivers\irqchip\irq-gic-v3-its.c

在这里插入图片描述

3.1.3 PCI MSI

对应的设备节点跟ITS驱动使用的一样的:

its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};

驱动代码:drivers\irqchip\irq-gic-v3-its-pci-msi.c,它只是在ITS下面再增加了一个处理层:

在这里插入图片描述

3.1.4 PCIe控制器

设备树:

        pcie0: pcie@f8000000 {compatible = "rockchip,rk3399-pcie";#address-cells = <3>;#size-cells = <2>;aspm-no-l0s;clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,<&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;clock-names = "aclk", "aclk-perf","hclk", "pm";bus-range = <0x0 0x1f>;max-link-speed = <1>;linux,pci-domain = <0>;msi-map = <0x0 &its 0x0 0x1000>;

里面的msi-map = <0x0 &its 0x0 0x1000>;是用来把PCIe设备映射到MSI控制器,它的格式为:

msi-map = <rid-base &msi-controller msi-base length>;
  • rid-base:第1个Request ID,就是使用<bus, dev, function>组成的一个数字
  • msi-controller:这个PCIe设备映射到哪个MSI控制器?
  • msi-base:第1个PCIe设备映射到MSI控制器哪个中断?
  • length:能映射多少个设备

3.2 分配中断

代码:drivers\nvme\host\pci.c

nvme_probe > nvme_probe_work > nvme_setup_io_queues pci_enable_msix_rangepci_enable_msix(dev, entries, nvec);msix_capability_init(dev, entries, nvec);pci_enable_msi_rangemsi_capability_init(dev, nvec);msix_capability_init/msi_capability_initpci_msi_setup_msi_irqspci_msi_domain_alloc_irqsmsi_domain_alloc_irqsret = ops->msi_prepare(domain, dev, nvec, &arg); // its_pci_msi_prepareits_pci_msi_prepare // irq-gic-v3-its-pci-msi.c// rid = (bus << 8) | (dev << 4) | functioninfo->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev);	return msi_info->ops->msi_prepare(...) // 上一层irq-gic-v3-its.cits_msi_preparedev_id = info->scratchpad[0].ul;  // ridits_dev = its_create_device(its, dev_id, nvec);// 从ITS全局的位图里找到空闲位 chunk// 一个chunk表示32个中断// its的hwirq = (chunk << 5) + 8192// 这也是GIC的hwirqlpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);// 等于(chunk << 5) + 8192 dev->event_map.lpi_base = lpi_base;__irq_domain_alloc_irqsirq_domain_alloc_irqs_recursiveret = domain->ops->alloc(domain, irq_base, nr_irqs, arg);its_irq_domain_allocerr = its_alloc_device_irq(its_dev, &hwirq);*hwirq = dev->event_map.lpi_base + idx;irq_domain_set_hwirq_and_chipirq_data->hwirq = hwirq;irq_data->chip = chip ? chip : &no_irq_chip;irq_domain_activate_irq(irq_data);domain->ops->activate(domain, irq_data);msi_domain_activateirq_chip_compose_msi_msg(irq_data, &msg)	// 构造msg,里面含有MSI或msi-x的addr/valits_irq_compose_msi_msgaddr = its->phys_base + GITS_TRANSLATER;msg->address_lo		= addr & ((1UL << 32) - 1);msg->address_hi		= addr >> 32;// its_get_event_id:// d->hwirq - its_dev->event_map.lpi_base;msg->data		= its_get_event_id(d);                   // 设置msi-x的entry地址	irq_chip_write_msi_msg(irq_data, &msg);data->chip->irq_write_msi_msg(data, msg);pci_msi_domain_write_msg__pci_write_msi_msg(desc, msg);__pci_write_msi_msg(desc, msg);// 对于MSI-Xwritel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);writel(msg->data, base + PCI_MSIX_ENTRY_DATA);// 对于MSIpci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl);pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,msg->address_lo);// 为PCI设备确定hwirq
its_domain_ops.alloc
its_irq_domain_allocits_alloc_device_irq*hwirq = dev->event_map.lpi_base + idx;


致谢

以上笔记源自韦东山老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!

在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!



相关文章:

MSI_MSI-X中断之源码分析

MSI_MSI-X中断之源码分析 文章目录MSI_MSI-X中断之源码分析一、 怎么发出MSI/MSI-X中断1.1 在RK3399上体验1.1.1 安装工具1.1.2 查看设备MSI-X信息1.1.3 验证MSI-X信息二、 怎么使用MSI/MSI-X三、 MSI/MSI-X中断源码分析3.1 IRQ Domain创建流程3.1.1 GIC3.1.2 ITS3.1.3 PCI MSI…...

Docker--consul

目录 前言 一、Consul 简介 1.1、 consul 概述 1.2 、consul 的两种模式 1.3、consul 提供的一些关键特性 二、Consul 容器服务更新与发现 三、consul 部署 3.2、查看集群信息 四、registrator服务器 consul-template 五、consul 多节点 前言 服务注册与发现是微服…...

ESP-01S使用AT指令连接阿里云

ESP-01S使用AT指令连接阿里云 烧录MQTT AT固件 出厂的ESP-01S是基本的AT指令固件&#xff0c;没有MQTT的&#xff0c;所以无法通过MQTT指令与云平台通信&#xff0c;需要烧录固件&#xff08;如果测试到有MQTT相关的指令&#xff0c;则不用重新烧录固件&#xff09; 固件烧录…...

【Kafka】【三】安装Kafka服务器

Kafka基本知识 Kafka介绍 Kafka是最初由Linkedin公司开发&#xff0c;是⼀个分布式、⽀持分区的&#xff08;partition&#xff09;、多副本的 &#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统&#xff0c;它的最⼤的特性就是可以实时的处理 …...

关于适配器模式,我遗漏了什么

近期有些tasks需要 重构or适配 老的代码。 与其向上面堆&#x1f4a9;&#xff0c;不如优雅的去解决。 首先我的问题在于&#xff0c;错误的把 堆屎的操作 &#xff0c;当作了适配器模式的操作。 比如原函数入参&#xff0c;需要更改某个属性&#xff0c;把这种操作外包一层…...

SQL Serve 日志体系结构

SQL Server 事务日志记录着 undo 及 redo 日志&#xff0c;为了保证数据库在崩溃后恢复&#xff0c;或者在正常数据库操作期间进行回滚&#xff0c;保证数据库事务完整性和持久化。如果没有事务日志记录&#xff0c;数据库在事务上将不一致&#xff0c;并且在数据库崩溃后可能导…...

【C++1】函数重载,类和对象,引用,string类,vector容器,类继承和多态,/socket,进程信号,public,ooci

文章目录1.函数重载&#xff1a;writetofile()&#xff0c;Ctrue和false&#xff0c;C0和非02.类和对象&#xff1a;vprintf2.1 构造函数&#xff1a;对成员变量初始化2.2 析构函数&#xff1a;一个类只有一个&#xff0c;不允许被重载3.引用&#xff1a;C中&取地址&#x…...

asio网络编程 tcp、udp、rpc

轻量级的tcp/udp/rpc库&#xff0c;简化socket程序编写。 同时&#xff0c;RPC部分也提供了方便易用的功能。 仓库地址 https://github.com/shuai132/asio_net asio_net a Tiny Async TCP/UDP/RPC library based on ASIO and RpcCore Features 简化TCP、UDP相关程序的编写…...

双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输(带源码)

Depth2Uart 双目测距------双目相机V1.0&#xff0c;将双目相机采集到任意一点的深度数据进行串口传输 一、项目说明/Overview 所实现的功能&#xff1a;基于Intel Realsense官方提供的SDK&#xff0c;双目深度相机能获取到相机任何一个像素点距离前方障碍物的距离&#xff0…...

jetson nano(ubuntu)安装Cmake

文章目录安装环境一.命令行安装二.Cmake源码编译安装安装环境 jetson nano 系统&#xff1a;4.6.1 一.命令行安装 sudo apt install cmake这种直接安装cmake的方式&#xff0c;其实安装的版本都太老了&#xff0c;这种方式不推荐 二.Cmake源码编译安装 更新一下系统软件 su…...

图的基本介绍和表示方式

图的基本介绍 为什么要有图这个基本数据结构? 我们还学习过线性表&#xff08;数组、队列、链表和栈&#xff09;和树&#xff0c;但是我们可以发现&#xff0c;线性表局限于一个直接前驱&#xff08;就是只能有唯一一个前面的结点&#xff09;和一个直接后继的&#xff08;…...

本周大新闻|传微软解散工业元宇宙团队,MIT研发垂直堆叠全彩Micro LED

本周大新闻&#xff0c;AR方面&#xff0c;消息称微软解散工业元宇宙团队&#xff1b;德国AR公司Gixel GmbH亮相&#xff1b;Brilliant推出单片式附加形态AR眼镜&#xff1b;MIT研发垂直堆叠全彩Micro LED&#xff1b;谷歌XR串流正式上线。VR方面&#xff0c;索尼发布了PS VR2的…...

SpringMVC:拦截器(12)

拦截器1. 拦截器概念2. 拦截器入门案例2.1 环境准备2.2 拦截器开发步骤1: 创建拦截器类步骤2: 配置拦截器类步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描步骤4: 简化SpringMvcSupport的编写5 测试3. 拦截器参数解析&#xff08;了解&#xff09;3.1 前置处理…...

计算机网络3:HTTP1.0和HTTP1.1的区别

目录1. HTTP是什么2.HTTP1.0和HTTP1.1的区别3.名词解释&#xff08;1&#xff09;If-Modified-Since&#xff08;IMS&#xff09;、Expires&#xff08;2&#xff09;If-None-Match&#xff0c;Etag&#xff08;3&#xff09;If-Unmodified-Since1. HTTP是什么 超文本传输协议…...

Urho3D 编辑器说明

Urho3D编辑器是一个脚本应用程序&#xff0c;可以与Urho3D播放器应用程序一起运行。要开始&#xff0c;请执行以下任意命令&#xff1a;&#xff08;在bin目录中&#xff09;Editor.bat、Editor.sh或Urho3DPlayer Scripts/Editor.as Urho3D播放器应用程序支持的所有命令行选项…...

C++类基础(十一)

运算符重载&#xff08;二&#xff09; ● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换 struct Str {int val 0;Str(int input): val(input){}auto operator(Str x){std::cout << "auto operator(Str x)\n";return Str(val x.val);} }; int …...

Windows安装系列:SVN Server服务

一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址&#xff1a;Download | VisualSVN Server 2、找到最新版本SVN 5.1.1&#xff0c;直接双击它&#xff0c;弹出如下安装界面 3、点击Next 4、勾选我接受&#xff0c; 点击"Next" 5、默认选项&#xff0c…...

快速傅里叶算法(FFT)快在哪里?

目录 前言 1、DFT算法 2、FFT算法 2.1 分类 2.2 以基2 DIT&#xff08;时间抽取&#xff09; FFT 算法为例 2.2.1 一次分解 2.2.2 多次分解 参考 前言 对信号分析的过程中&#xff0c;为了能换一个角度观察问题&#xff0c;很多时候需要把时域信号波形变换到频域进行分…...

利用Markdown写学术论文资料汇总贴

1是最详细的&#xff0c;重点看&#xff01; Markdown 写作&#xff0c;Pandoc 转换&#xff1a;我的纯文本学术写作流程 2补充一些细节&#xff0c;也可以看看。 用Markdown写作学术论文 3写得和上面差不多&#xff0c;如果上面两篇有什么问题还没解决&#xff0c;可以看看…...

MySQL 高级查询

目录1.左关联2.右关联3.子查询4.联合查询5.分组查询1.左关联 MySQL中的左关联&#xff08;Left Join&#xff09;是一种基于共同列的连接操作&#xff0c; 它将左侧表中的所有行与右侧表中匹配的行结合在一起&#xff0c; 如果右侧表中没有匹配的行&#xff0c;则结果集中右侧…...

JavaSE学习day4_01 循环for,while,do...while

1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的&#xff0c;所以用while格式的 代码示例&#xff1a; while(true){} 1.2 跳转控制语句&#xff08;掌握&#xff09; 跳转控制语句&…...

C/C++中的static关键字

概述在C/C中都有static关键字的使用&#xff0c;可以分别修饰变量和函数&#xff0c;分为静态变量【静态成员】、静态成员函数。2. static用法概况静态变量的作用范围在一个文件内&#xff0c;程序开始时分配空间&#xff0c;结束时释放空间&#xff0c;默认初始化为0&#xff…...

67 自注意力【动手学深度学习v2】

67 自注意力【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV19o4y1m7mo/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 给定长为n 的序列&#xff0c;每个xi为长为d的向量&#xff0c;自注意力将xi 既当…...

电子学会2022年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析

青少年软件编程&#xff08;图形化&#xff09;等级考试试卷&#xff08;二级&#xff09; 一、单选题(共25题&#xff0c;共50分) 1. 一个骰子&#xff0c;从3个不同角度看过去的点数如图所示&#xff0c;请问5的对面是什么点数&#xff1f;&#xff08; &#xff09; …...

关于链表中插入结点的操作……

服了&#xff0c;好久没敲链表了&#xff0c;这都忘了 newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur-…...

【项目精选】百货中心供应链管理系统

点击下载源码 近年来&#xff0c;随着计算机技术的发展&#xff0c;以及信息化时代下企业对效率的需求&#xff0c;计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环&#xff0c;为了应对新兴消费方式的冲击&#xff0c;从供货到销…...

Qt优秀开源项目之十六:SQLite数据库管理系统—SQLiteStudio

首先&#xff0c;感谢CSDN官方认可 SQLiteStudio是一款开源、跨平台&#xff08;Windows、Linux和MacOS&#xff09;的SQLite数据库管理系统。 github地址&#xff1a;https://github.com/pawelsalawa/sqlitestudio 官网&#xff1a;https://sqlitestudio.pl/ 特性很多&#xf…...

Python __doc__属性:查看文档

在使用 dir() 函数和 __all__ 变量的基础上&#xff0c;虽然我们能知晓指定模块&#xff08;或包&#xff09;中所有可用的成员&#xff08;变量、函数和类&#xff09;&#xff0c;比如&#xff1a;import string print(string.__all__)程序执行结果为&#xff1a;[ascii_lett…...

电子科技大学操作系统期末复习笔记(一):操作系统概述

目录 前言 操作系统概述 操作系统的目标与功能 操作系统的定义 目标 功能 操作系统的历史 单用户系统 简单批处理系统 多道批处理系统 分时系统 个人电脑 → 分布式系统 → 互联网时代 → 移动计算时代 → ...... 实时系统 操作系统的基本特征 并发 共享 虚拟…...

[实践篇]13.20 Qnx进程管理slm学习笔记(三)

【QNX Hypervisor 2.2用户手册】目录(完结) 4.2 模块 我们可以将组件组合成一个模块。模块中的进程可以组成一个子系统,也可以用于建立一组系统状态,例如基本操作和各种更高级别操作。注意,必须命名模块,以便可以在内部引用它们。而且每个模块必须描述成一个元素,形势如…...

想开一个网站开发的公司/班级优化大师怎么用

免费开通大数据服务&#xff1a;https://www.aliyun.com/product/odps “用户每天产生的日志量大约在2TB。我们需要将这些海量的数据导入云端&#xff0c;然后分天、分小时的展开数据分析作业&#xff0c;分析结果再导入数据库和报表系统&#xff0c;最终展示在运营人员面前。”…...

有域名和主机怎么做网站/护肤品营销策划方案

《大学计算机基础实训教程参考答案(更新)》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《大学计算机基础实训教程参考答案(更新)(12页珍藏版)》请在人人文库网上搜索。1、第8章 计算机基础知识练习答案一、单项选择题1. A2. B3. A4. A5. A6. C7. C8. C9. D10. A11. …...

建设银行招标网站/深圳网络推广专员

返回目录 今天写缓存篇的第一篇文章&#xff0c;在写完目录后&#xff0c;得到了一些朋友的关注&#xff0c;这给我之后的写作带来了无穷的力量&#xff0c;在这里&#xff0c;感谢那几位伙伴&#xff0c;哈哈&#xff01; 书归正传&#xff0c;今天我带来一个Static静态成员的…...

坪地网站建设市场/开通网站需要多少钱

...

网站怎么做显得简洁美观/交换链接的方法

大数据实时计算工程师/Hadoop工程师/数据分析师职业路线图 描述本路线图是一个专门针对大数据实时处理、Hadoop工程师和数据分析师所设计的课程体系介绍&#xff0c;在实时计算方向主要包括了从数据收集框架、集群协调框架、数据缓存框架到实时计算框架都全面进行深度解析&…...

wordpress 热门排序/seo草根博客

Vue,v-for循环遍历方式 1.v-for循环普通数组 item是自定义名称&#xff0c; in后面加的是 list这个普通数组 1 <!DOCTYPE html>2 <html>3 <head>4 <meta charset"utf-8">5 <title></title>6 </head&…...