Intel x86_64 PMU简介

news2024/11/28 20:40:48

文章目录

  • 前言
  • 一、性能监控概述
  • 二、CPUID information
  • 三、架构性能监控
    • 3.1 架构性能监控 Version 1
      • 3.1.1 架构性能监控 Version 1 Facilities
      • 3.1.2 预定义的体系结构性能事件
      • 3.1.3 cmask demo测试
  • 参考资料

前言

Intel 64 和 IA-32 架构提供了 PMU(Performance Monitoring Unit:性能监控单元)设施用来监控性能。PMU 是内置于处理器内部的硬件,用于测量其性能参数,例如指令周期、高速缓存命中、高速缓存未命中、分支未命中等。性能监控事件提供了描述编程指令序列和微体系结构子系统之间交互的工具。

一些性能分析工具使用性能监控事件,它提供了基于事件的采样微架构分析类型,以了解代码如何有效地使用硬件资源,并推荐相关的优化技术。
intel_pmu插件收集由Linux perf接口提供的信息,perf接口提供了丰富的针对特定硬件功能的通用抽象。所有事件都是在每个核心基础上报告的。
性能计数器是CPU硬件寄存器,它计算硬件事件,如执行的指令、缓存丢失或分支预测错误。它们构成了分析应用程序跟踪动态控制流和识别热点的基础。

一、性能监控概述

Pentium处理器引入了性能监控通过一组 model-specific 的性能监控计数器MSRs,这些计数器允许选择要监视和测量的处理器性能参数,从这些计数器获得的信息可用于调优系统和编译器性能。

在 Intel P6 系列处理器中,性能监控机制得到了增强,允许监控更广泛的事件选择,并允许监控更多的控制事件。 接下来,基于 Intel NetBurst 微架构的 Intel 处理器引入了一种分布式的性能监控机制和性能事件。

为Pentium、P6系列和基于Intel NetBurst微架构的Intel处理器定义的性能监视机制和性能事件不是架构性的。它们都是特定于模型的(在处理器家族之间不兼容)。英特尔酷睿Solo和酷睿Duo处理器支持一组架构性能事件和一组非架构性能事件。新一代的Intel处理器支持增强的架构性能事件和非架构性能事件。

从英特尔酷睿Solo和酷睿Duo处理器开始,有两类性能监控功能:
第一个类支持使用计数或基于中断的事件抽样使用来监控性能的事件。这些事件是非体系结构的,并且因处理器模型的不同而不同。它们类似于Pentium M处理器中的那些。这些非体系结构性能监视事件特定于微体系结构,并可能随着增强而改变。

第二类性能监视功能称为体系结构性能监视。这个类支持相同的计数和基于中断的事件采样用法,使用更小的可用事件集。架构性能事件的可见行为在处理器实现中是一致的。架构性能监视功能的可用性是使用CPUID.0AH枚举的。这些事件将在第二节中讨论。

二、CPUID information

CPUID.EAX = 0AH (* Returns Architectural Performance Monitoring leaf. *)
当 CPUID 在 EAX 设置为 0AH 的情况下执行时,处理器会返回有关支持架构性能监视功能的信息。 version ID大于0 支持架构性能监控:
在这里插入图片描述
对于架构性能监控功能的每个版本,软件必须枚举 leaf 以发现处理器中可用的编程工具和架构性能事件。

三、架构性能监控

当性能监视事件跨微架构表现一致时,它们就是架构性的。英特尔酷睿Solo和酷睿Duo处理器引入了架构性能监控。该特性为软件提供了枚举性能事件的机制,并为事件提供了配置和计数功能。

架构性能监视确实允许跨处理器实现的增强。The CPUID.0AH leaf 为每个增强提供版本号。英特尔酷睿Solo和酷睿Duo处理器支持版本号为1的基本功能。基于Intel Core微架构的处理器,至少支持底层架构的性能监控功能。英特尔酷睿2双核处理器t7700和基于英特尔酷睿微架构的新处理器都支持基本功能和增强的架构性能监控(版本号为2)。

45 nm和32 nm Intel Atom处理器以及基于Silvermont微架构的Intel Atom处理器支持versionID 1、2和3所提供的功能;CPUID.0AH:EAX[7:0]报告versionID = 3,表示体系结构性能监控能力的总和。基于Airmont微架构的Intel Atom处理器支持与基于Silvermont微架构的处理器相同的性能监控能力。基于Goldmont和Goldmont Plus微架构的Intel Atom处理器支持versionID 4。从基于Tremont微架构的处理器开始的英特尔Atom处理器支持versionID 5。
基于Nehalem through Broadwell微架构的Intel Core处理器和相关的Intel Xeon处理器家族支持ID 3版本。基于Skylake到Coffee Lake微架构的英特尔处理器支持versionID 4。从基于Ice Lake微架构的处理器开始的英特尔处理器支持versionID 5

我这里只介绍英特尔处理器支持版本号为1的基本功能。

3.1 架构性能监控 Version 1

配置体系结构性能监视事件涉及编程性能事件选择寄存器。性能事件选择MSRs的数量有限(IA32_PERFEVTSELx MSRs)。性能监控事件的结果在性能监控指标(IA32_PMCx MSR)中上报。性能监视计数器与性能监视选择寄存器配对。

性能监控选择寄存器和计数器在以下方面具有架构性:
(1)IA32_PERFEVTSELx的位域布局在微架构中是一致的。
(2)在微架构中,IA32_PERFEVTSELx msr的地址保持不变。
(3)在微架构中,IA32_PMC msr的地址保持不变。
(4)每个逻辑处理器都有自己的一组IA32_PERFEVTSELx和IA32_PMCx msr。共享处理器核心的逻辑处理器之间不共享配置工具和计数器。

架构性能监控提供了一种 CPUID 机制,用于枚举以下信息:
(1) 逻辑处理器中软件可用的性能监控计数器的数量(每个 IA32_PERFEVTSELx MSR 与相应的 IA32_PMCx MSR 配对)。
(2)每个 IA32_PMCx 支持的位数。
(3) 逻辑处理器中支持的架构性能监控事件的数量。

软件可以使用 CPUID 来发现架构性能监控可用性 (CPUID.0AH)。 架构性能监控叶提供与处理器中可用的架构性能监控的版本号相对应的标识符。

在架构性能监控的初始实施中; 软件可以确定每个内核支持多少 IA32_PERFEVTSELx/ IA32_PMCx MSR 对、PMC 的位宽以及可用的架构性能监控事件的数量。

3.1.1 架构性能监控 Version 1 Facilities

架构性能监控工具包括一组性能监控计数器和性能事件选择寄存器。 这些 MSR 具有以下属性:
(1)IA32_PMCx MSR 从地址 0C1H 开始,占用 MSR 地址空间的连续块; 使用 CPUID.0AH:EAX[15:8] 报告每个逻辑处理器的 MSR 数量。 请注意,这可能与硬件上存在的物理计数器的数量不同,因为以更高权限级别(例如,VMM)运行的代理可能不会公开所有计数器。
(2)IA32_PERFEVTSELx MSR 从地址 186H 开始并占用 MSR 地址空间的一个连续块。 每个性能事件选择寄存器都与 0C1H 地址块中的相应性能计数器配对。请注意,IA32_PERFEVTSELx MSR 的数量可能与硬件上存在的物理计数器的数量不同,因为以更高权限级别(例如,VMM)运行的代理可能不会公开所有计数器。
(3)IA32_PMCx MSR 的位宽使用 CPUID.0AH:EAX[23:16] 报告。 这是读取操作的有效位数。 在写操作中,MSR 的低 32 位可以写入任意值,高位从第 31 位的值进行符号扩展。
(4)IA32_PERFEVTSELx MSR 的位域布局是在架构上定义的。

有关 IA32_PERFEVTSELx MSR 的位域布局,请参考下图。 位字段是:
在这里插入图片描述
(1)Event select field (bits 0 through 7):选择用于检测微体系结构条件的事件逻辑单元。 该字段的值集是在架构上定义的; 每个值对应一个事件逻辑单元,用于架构性能事件。 使用 CPUID.0AH:EAX 查询架构事件的数量。 处理器可能仅支持预定义值的子集。
(2)Unit mask (UMASK) field (bits 8 through 15):这些位限定所选事件逻辑单元检测到的条件。 每个事件逻辑单元的有效 UMASK 值特定于该单元。 对于每个架构性能事件,其对应的 UMASK 值定义了特定的微架构条件。
(3)USR (user mode) flag (bit 16):指定当逻辑处理器以特权级别 1、2 或 3 运行时计算选定的微体系结构条件。此标志可与 OS 标志一起使用。
(4)OS (operating system mode) flag (bit 17):指定当逻辑处理器以特权级别 0 运行时计算选定的微体系结构条件。此标志可与 USR 标志一起使用。
(5)E (edge detect) flag (bit 18):启用(设置时)所选微架构条件的边缘检测。对于可以由其他字段表示的任何条件,逻辑处理器计算 deasserted to asserted 转换的次数。该机制不允许区分 back-to-back assertions。
这种机制使软件不仅可以测量在特定状态下花费的时间比例,还可以测量在这种状态下花费的平均时间长度(例如,等待中断服务所花费的时间)。
(6)PC (pin control) flag (bit 19):从 Sandy Bridge 微架构开始,该位被保留(不可写)。 在基于先前微架构的处理器上,逻辑处理器切换 PMi 引脚并在性能监控事件发生时递增计数器; 当清零时,处理器在计数器溢出时切换 PMi 引脚。引脚的切换定义为对单个总线时钟的引脚assertion,然后 deassertion。
(7)INT (APIC interrupt enable) flag (bit 20):设置后,逻辑处理器在计数器溢出时通过其本地 APIC 生成异常。
(8)EN (Enable Counters) Flag (bit 22):设置后,在相应的性能监控计数器中启用性能计数; 当清零时,相应的计数器被禁用。 在写入 IA32_PMCx 之前,必须通过设置 IA32_PERFEVTSELx[bit 22] = 0 来禁用 UMASK 的事件逻辑单元。
(9)INV (invert) flag (bit 23):设置后,反转 counter-mask (CMASK) 比较,以便可以进行大于或等于和小于比较(0:大于或等于;1:小于)。 请注意,如果 counter-mask被编程为零,则忽略 INV 标志。
(10)Counter mask (CMASK) field (bits 24 through 31):当此字段不为零时,逻辑处理器将此掩码与在单个周期内检测到的微体系结构条件的事件计数进行比较。 如果事件计数大于或等于此掩码,则计数器加一。 否则计数器不会增加。
此掩码旨在用于软件来描述可以计算每个周期多次出现的微架构条件(例如,每个时钟退出两条或更多条指令;或总线队列占用)如果counter-mask字段为 0,则计数器在每个周期增加与多次发生相关的事件计数。

3.1.2 预定义的体系结构性能事件

下表列出了架构定义的事件:
在这里插入图片描述

[root@localhost ~]# cat /sys/devices/cpu/events/
branch-instructions  bus-cycles           cache-references     instructions         mem-stores
branch-misses        cache-misses         cpu-cycles           mem-loads            ref-cycles
[root@localhost ~]# cat /sys/devices/cpu/events/cpu-cycles
event=0x3c
[root@localhost ~]# cat /sys/devices/cpu/events/branch-misses
event=0xc5
[root@localhost ~]# cat /sys/devices/cpu/events/branch-instructions
event=0xc4

支持架构性能监控的处理器可能不支持所有预定义的架构性能事件,架构事件的数量通过CPUID.0AH:EAX[31:24] 说明,而 CPUID.0AH:EBX 中的非零位表示任何不可用的架构事件。每个体系结构性能事件的行为预计在支持该事件的所有处理器上都是一致的。

所涉及名词解释:
retired :消耗(指令的消耗数目),对于包含多个微操作(micro-op)的指令,其只对最后一个微操作的指令引退进行计数,即只计数一次。
at retirement (指令)引退。

微架构之间的细微差异如下所示:
(1)UnHalted Core Cycles — Event select 3CH, Umask 00H
当特定内核上的时钟信号正在运行(未停止)时,此事件计算内核时钟周期。 在以下情况下,计数器不会前进:
— an ACPI C-state other than C0 for normal operation
— HLT
— STPCLK# pin asserted
— being throttled by TM1
— during the frequency switching phase of a performance state transition (see Chapter 14, “Power and
Thermal Management”)

此事件的性能计数器计算使用不同内核时钟频率的性能状态转换。

(2)Instructions Retired — Event select C0H, Umask 00H
此事件计算指令引退时的指令数。 对于由多个微操作组成的指令,此事件计算指令的最后一个微操作的退出。 带有 REP 前缀的指令算作一条指令(不是每次迭代)。 多操作指令的最后一个微操作退出之前的故障不计算在内。
此事件在 VM 退出条件下不会增加。 计数器在硬件中断、陷阱和内部中断处理程序期间继续计数

(3)UnHalted Reference Cycles — Event select 3CH, Umask 01H
此事件在内核上的时钟信号运行时以固定频率计算参考时钟周期。 事件以固定频率计数,与性能状态转换导致的核心频率变化无关。 处理器可能会以不同的方式实现此行为。 当前的实现使用核心晶体时钟、TSC 或总线时钟。 由于实现之间的速率可能不同,因此软件应将其校准为具有已知频率的时间源。

(4)Last Level Cache References — Event select 2EH, Umask 4FH
此事件对源自内核的请求计数,这些请求引用最后一级片上高速缓存中的高速缓存行。 事件计数包括由于一级缓存硬件预取器导致的推测和缓存行填充,但可能不包括由于其他硬件预取器导致的缓存行填充。
因为缓存层次结构、缓存大小和其他特定于实现的特性; 不建议通过值比较来估计性能差异。

(5)Last Level Cache Misses — Event select 2EH, Umask 41H
此事件计算对最后一级片上缓存的引用的每个缓存未命中情况。 事件计数可能包括由于一级缓存硬件预取器导致的推测和缓存行填充,但可能不包括由于其他硬件预取器导致的缓存行填充。
因为缓存层次结构、缓存大小和其他特定于实现的特性; 不建议通过值比较来估计性能差异。

(6)Branch Instructions Retired — Event select C4H, Umask 00H
此事件计算指令引退时的分支指令。 它计算分支指令的最后一个微操作的退出。

(7)All Branch Mispredict Retired — Event select C5H, Umask 00H
此事件在指令引退时计算错误预测的分支指令,它计算架构执行路径中分支指令的最后一个微操作的退出以及在分支预测硬件中经历的错误预测。
分支预测硬件在微架构中是特定于实现的; 不建议通过值比较来估计性能差异。

(8)Topdown Slots — Event select A4H, Umask 01H
此事件计算未暂停逻辑处理器的可用插槽( slots)总数。
自顶向下微体系结构分析方法(Top-down Microarchitecture Analysis method)所采用的 the narrowest pipeline 的机器宽度增加事件。该计数分布在支持英特尔超线程技术的处理器中共享相同物理核心的未停止逻辑处理器(超线程)之间。
软件可以将此事件用作自顶向下微体系结构分析方法的顶级指标的统计基准(denominator)。

其中各个事件的值计算在Linux内核源码中的计算:

#define ARCH_PERFMON_EVENTSEL_EVENT			0x000000FFULL
#define ARCH_PERFMON_EVENTSEL_UMASK			0x0000FF00ULL
#define ARCH_PERFMON_EVENTSEL_USR			(1ULL << 16)
#define ARCH_PERFMON_EVENTSEL_OS			(1ULL << 17)
#define ARCH_PERFMON_EVENTSEL_EDGE			(1ULL << 18)
#define ARCH_PERFMON_EVENTSEL_PIN_CONTROL		(1ULL << 19)
#define ARCH_PERFMON_EVENTSEL_INT			(1ULL << 20)
#define ARCH_PERFMON_EVENTSEL_ANY			(1ULL << 21)
#define ARCH_PERFMON_EVENTSEL_ENABLE			(1ULL << 22)
#define ARCH_PERFMON_EVENTSEL_INV			(1ULL << 23)
#define ARCH_PERFMON_EVENTSEL_CMASK			0xFF000000ULL

#define X86_RAW_EVENT_MASK		\
	(ARCH_PERFMON_EVENTSEL_EVENT |	\
	 ARCH_PERFMON_EVENTSEL_UMASK |	\
	 ARCH_PERFMON_EVENTSEL_EDGE  |	\
	 ARCH_PERFMON_EVENTSEL_INV   |	\
	 ARCH_PERFMON_EVENTSEL_CMASK)
ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
{
	u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
	u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
	bool edge  = (config & ARCH_PERFMON_EVENTSEL_EDGE);
	bool pc    = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
	bool any   = (config & ARCH_PERFMON_EVENTSEL_ANY);
	bool inv   = (config & ARCH_PERFMON_EVENTSEL_INV);
	......
}
PMU_FORMAT_ATTR(event,	"config:0-7"	);
PMU_FORMAT_ATTR(umask,	"config:8-15"	);
PMU_FORMAT_ATTR(edge,	"config:18"	);
PMU_FORMAT_ATTR(pc,	"config:19"	);
PMU_FORMAT_ATTR(any,	"config:21"	); /* v3 + */
PMU_FORMAT_ATTR(inv,	"config:23"	);
PMU_FORMAT_ATTR(cmask,	"config:24-31"	);

static struct attribute *intel_arch_formats_attr[] = {
	&format_attr_event.attr,
	&format_attr_umask.attr,
	&format_attr_edge.attr,
	&format_attr_pc.attr,
	&format_attr_inv.attr,
	&format_attr_cmask.attr,
	NULL,
};

3.1.3 cmask demo测试

写一个内核模块测试一台intel处理器所预定义的架构性能事件数目:

#include <linux/kernel.h>
#include <linux/module.h>


unsigned int pmu_mask(unsigned int sig)
{
	unsigned int mask;

	mask = (sig >> 24) & 0xff;

	return mask;
}


//内核模块初始化函数
static int __init lkm_init(void)
{
	unsigned int eax = 0;
	unsigned int ebx = 0;
	unsigned int ecx = 0;
	unsigned int edx = 0;

    unsigned int cmask = 0;

	cpuid(0x0a, &eax, &ebx, &ecx, &edx);

    cmask = pmu_mask(eax);
	
	printk("cmask = %d\n", cmask);
		
	return 0;
}

//内核模块退出函数
static void __exit lkm_exit(void)
{
	printk(KERN_DEBUG "exit\n");
}

module_init(lkm_init);
module_exit(lkm_exit);

MODULE_LICENSE("GPL");
root@localhost intel_pmu]# dmesg -c
[13670.361813] cmask = 7

虽然有很多PMC,但Intel选择了七个作为“架构集”(这里没有包括Topdown Slots架构性能事件),这些架构集提供了一些核心功能的高级概述。

参考资料

Linux 3.10.0
intel v3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/331368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle Data Guard Apply服务

1. Apply服务介绍 Apply服务自动应用redo到备数据库来保持与主数据库的同步和允许事务一致性访问数据。 缺省情况下&#xff0c;Apply服务等待备redo日志文件进行归档&#xff0c;然后再应用归档日志文件包含的redo。然而&#xff0c;可以启用实时Apply&#xff0c;允许当前的…

CentOS8基础篇2:文件系统

一、文件系统概述 1.文件系统的基本概念 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统&#xff0c;简称文件系统。它规定了文件的存储方式及文件索引方式等信息。文件系统主要由三部分组成&#xff0c;分别是与文件管理相关的软件、被管理的文件和实施文件管…

ip-guard如何查看客户端连接的服务器IP地址?

在客户端上通过“运行”输入win.ini打开文件(在目录C:\\Windows\\),可以从里面找到一个字段SIP,比如SIP=3232237616 再将其换算成16进制数为c0a80830

每天10个前端小知识 【Day 8】

前端面试基础知识题 1. Javascript中如何实现函数缓存&#xff1f;函数缓存有哪些应用场景&#xff1f; 函数缓存&#xff0c;就是将函数运算过的结果进行缓存。本质上就是用空间&#xff08;缓存存储&#xff09;换时间&#xff08;计算过程&#xff09;&#xff0c; 常用于…

在CANoe/CANalyzer中给CAN Log.asc/blf文件“瘦身”

案例背景&#xff08;共7页精讲&#xff09;&#xff1a; 该篇博文将告诉您&#xff0c;如何给离线文件CAN Log.asc/blf文件“瘦身”&#xff1a;批量删除/过滤 CAN Log中&#xff0c;不需要的CAN ID和CAN channel。 目录 1 准备工作 2 插入CAN Filter 3 保存“瘦身” 后的…

一种RK3399+MIPI+FPGA的高速工业相机的设计方案(一)

目 前 &#xff0c; 嵌 入 式 相 机 逐 渐 代 替 了 传 统 相 机 进 入 大 众 的 视 野 &#xff0c; 应 用 在 公 安 刑 侦 、 生 物 医 学和 文 物 保 护 等 诸 多 领 域 。 但 是 随 着 人 们 对 图 像 视 觉 成 像 质 量 追 求 的 提 升 &#xff0c; 图 像 传 感 器 的 特…

ESP32S3系列--SPI主机驱动详解(一)

一、目的SPI是一种串行同步接口&#xff0c;可用于与外围设备进行通信。ESP32S3自带4个SPI控制器外设&#xff08;Master&#xff09;&#xff0c;其中SPI0/SPI1内部专用,共用一组信号线,通过一个仲裁器访问外部Flash和PSRAM&#xff1b;SPI2/3各自使用一组信号线&#xff1b;开…

【C++】二叉树的前序中序后序非递归实现

文章目录二叉树的前序遍历二叉树的中序遍历二叉树的后序遍历总结二叉树的前序遍历 前序遍历的顺序是根、左、右。任何一颗树都可以认为分为左路节点&#xff0c;左路节点的右子树。先访问左路节点&#xff0c;再来访问左路节点的右子树。把访问左路节点的右子树看成一个子问题…

VUE3 插件的开发和使用

在构建 Vue 项目的过程中&#xff0c;离不开各种开箱即用的插件支持&#xff0c;用以快速完成需求&#xff0c;避免自己造轮子。 在 Vue 项目里&#xff0c;可以使用针对 Vue 定制开发的专属插件&#xff0c;也可以使用无框架依赖的通用 JS 插件&#xff0c;插件的表现形式也是…

51单片机学习笔记_11 蜂鸣器,识简谱,根据简谱编写蜂鸣器代码

蜂鸣器实验 蜂鸣器简单地说&#xff0c;就是电磁线圈和磁铁对振动膜的作用。 单片机的是无源蜂鸣器&#xff0c;不能一直充电&#xff0c;需要外部控制器发送震荡信号&#xff0c;可以改变频率产生不同的音色、音调。 大多数有源蜂鸣器则没有这个效果&#xff0c;有源蜂鸣器…

JavaScript(四)-全面详解(学习总结---从入门到深化)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主,Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4e7;如果文章…

JAVA开发(Redis的主从与集群)

现在web项目无处不在使用缓存技术&#xff0c;redis的身影可谓无处不在。但是又有多少项目使用到的是redis的集群&#xff1f;大概很多项目只是用到单机版的redis吧。作为缓存的一块&#xff0c;set &#xff0c;get数据。用的不亦乐乎。但是对于高可用系统来说&#xff0c;数据…

Tomcat简介

目录 一、Tomcat简介 二、下载安装Tomcat 三、利用Tomcat部署静态页面 一、Tomcat简介 Tomcat是一个HTTP服务器&#xff0c;可以按照HTTP的格式来解析请求来调用用户指定的相关代码然后按照HTTP的格式来构造返回数据。 二、下载安装Tomcat 进入Tomcat官网选择与自己电脑…

电子科技大学人工智能期末复习笔记(二):MDP与强化学习

目录 前言 期望最大搜索&#xff08;Expectimax Search&#xff09; ⭐马尔科夫决策&#xff08;MDP&#xff09;——offline&#xff08;超重点&#xff09; 先来看一个例子 基本概念 政策&#xff08;Policy&#xff09; 折扣&#xff08;Discounting&#xff09; 如…

Mysql中的事务

1. MyIsam是不支持事务的&#xff0c; InnoDB支持 2.事务的四大特性ACID 原子性&#xff08;Atomicity&#xff09;&#xff1a;一个事务中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#xff0c;不会结束在中间某个环节&#xff0c;而且事务在执行过程中…

PythonWeb开发基础(四 完)Response使用及wsgify装饰器

课程地址&#xff1a;Python 工程师进阶技术图谱 文章目录&#x1f33e; Response使用及wsgify装饰器1、Response的使用2、wsgify装饰器&#x1f33e; Response使用及wsgify装饰器 1、Response的使用 前面一节我们知道了&#xff0c;使用webob的Request模块可以很方便地对请求…

若依框架---PageHelper分页(十五)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

STM32开发(7)----CubeMX配置串口通讯(轮询方式)

CubeMX配置串口通讯&#xff08;轮询方式&#xff09;前言一、串口的介绍二、实验过程1.实验材料2.STM32CubeMX配置PWM3.代码实现重载printf轮询接收4.编译烧录5.硬件连接6.实验结果重载printf结果串口轮询接收结果总结前言 本章介绍使用STM32CubeMX对串口进行配置的方法&…

​力扣解法汇总1797. 设计一个验证系统

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 你需要设计一个包含验证码的验证系统。每一次验证中&#xff0c;用户会收到一个…

vue:自定义组件如何使用v-model

问题&#xff1a; 在使用自定义组件时&#xff0c;我们有时候需要使用 v-model 来双向绑定。方法&#xff1a; 在vue中&#xff0c;v-model 的值相当于默认传递了一个名为 value 的 prop 和一个名为 input 的事件&#xff08;注意&#xff0c;这个value的prop是需要在自定义组件…