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

动手学深度学习12.3.自动并行-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。

本节课程地址:无

本节教材地址:12.3. 自动并行 — 动手学深度学习 2.0.0 documentation

本节开源代码:...>d2l-zh>pytorch>chapter_optimization>auto-parallelism.ipynb


自动并行

深度学习框架(例如,MxNet、飞桨和PyTorch)会在后端自动构建计算图。利用计算图,系统可以了解所有依赖关系,并且可以选择性地并行执行多个不相互依赖的任务以提高速度。例如,12.2节 中的 图12.2.2 独立初始化两个变量。因此,系统可以选择并行执行它们。

通常情况下单个操作符将使用所有CPU或单个GPU上的所有计算资源。例如,即使在一台机器上有多个CPU处理器,dot操作符也将使用所有CPU上的所有核心(和线程)。这样的行为同样适用于单个GPU。因此,并行化对单设备计算机来说并不是很有用,而并行化对于多个设备就很重要了。虽然并行化通常应用在多个GPU之间,但增加本地CPU以后还将提高少许性能。例如, (Hadjis et al., 2016) 则把结合GPU和CPU的训练应用到计算机视觉模型中。借助自动并行化框架的便利性,我们可以依靠几行Python代码实现相同的目标。对自动并行计算的讨论主要集中在使用CPU和GPU的并行计算上,以及计算和通信的并行化内容。

请注意,本节中的实验至少需要两个GPU来运行。

import torch
from d2l import torch as d2l

基于GPU的并行计算

从定义一个具有参考性的用于测试的工作负载开始:下面的run函数将执行 10 次矩阵-矩阵乘法时需要使用的数据分配到两个变量(x_gpu1x_gpu2)中,这两个变量分别位于选择的不同设备上。

devices = d2l.try_all_gpus()
def run(x):return [x.mm(x) for _ in range(50)]x_gpu1 = torch.rand(size=(4000, 4000), device=devices[0])
x_gpu2 = torch.rand(size=(4000, 4000), device=devices[1])

现在使用函数来处理数据。通过在测量之前需要预热设备(对设备执行一次传递)来确保缓存的作用不影响最终的结果。torch.cuda.synchronize()函数将会等待一个CUDA设备上的所有流中的所有核心的计算完成。函数接受一个device参数,代表是哪个设备需要同步。如果device参数是None(默认值),它将使用current_device()找出的当前设备。

run(x_gpu1)
run(x_gpu2)  # 预热设备
torch.cuda.synchronize(devices[0])
torch.cuda.synchronize(devices[1])with d2l.Benchmark('GPU1 time'):run(x_gpu1)torch.cuda.synchronize(devices[0])with d2l.Benchmark('GPU2 time'):run(x_gpu2)torch.cuda.synchronize(devices[1])

输出结果:
GPU1 time: 1.4571 sec
GPU2 time: 1.4560 sec

如果删除两个任务之间的synchronize语句,系统就可以在两个设备上自动实现并行计算。

with d2l.Benchmark('GPU1 & GPU2'):run(x_gpu1)run(x_gpu2)torch.cuda.synchronize()

输出结果:
GPU1 & GPU2: 1.5222 sec

在上述情况下,总执行时间小于两个部分执行时间的总和,因为深度学习框架自动调度两个GPU设备上的计算,而不需要用户编写复杂的代码。

并行计算与通信

在许多情况下,我们需要在不同的设备之间移动数据,比如在CPU和GPU之间,或者在不同的GPU之间。例如,当执行分布式优化时,就需要移动数据来聚合多个加速卡上的梯度。让我们通过在GPU上计算,然后将结果复制回CPU来模拟这个过程。

def copy_to_cpu(x, non_blocking=False):return [y.to('cpu', non_blocking=non_blocking) for y in x]with d2l.Benchmark('在GPU1上运行'):y = run(x_gpu1)torch.cuda.synchronize()with d2l.Benchmark('复制到CPU'):y_cpu = copy_to_cpu(y)torch.cuda.synchronize()

输出结果:
在GPU1上运行: 1.8508 sec
复制到CPU: 3.1686 sec

这种方式效率不高。注意到当列表中的其余部分还在计算时,我们可能就已经开始将y的部分复制到CPU了。例如,当计算一个小批量的(反传)梯度时。某些参数的梯度将比其他参数的梯度更早可用。因此,在GPU仍在运行时就开始使用PCI-Express总线带宽来移动数据是有利的。在PyTorch中,to()copy_()等函数都允许显式的non_blocking参数,这允许在不需要同步时调用方可以绕过同步。设置non_blocking=True以模拟这个场景。

with d2l.Benchmark('在GPU1上运行并复制到CPU'):y = run(x_gpu1)y_cpu = copy_to_cpu(y, True)torch.cuda.synchronize()

输出结果:
在GPU1上运行并复制到CPU: 2.6157 sec

两个操作所需的总时间少于它们各部分操作所需时间的总和。请注意,与并行计算的区别是通信操作使用的资源:CPU和GPU之间的总线。事实上,我们可以在两个设备上同时进行计算和通信。如上所述,计算和通信之间存在的依赖关系是必须先计算y[i],然后才能将其复制到CPU。幸运的是,系统可以在计算y[i]的同时复制y[i-1],以减少总的运行时间。

最后,本节给出了一个简单的两层多层感知机在CPU和两个GPU上训练时的计算图及其依赖关系的例子,如 图12.3.1 所示。手动调度由此产生的并行程序将是相当痛苦的。这就是基于图的计算后端进行优化的优势所在。

小结

  • 现代系统拥有多种设备,如多个GPU和多个CPU,还可以并行地、异步地使用它们。
  • 现代系统还拥有各种通信资源,如PCI Express、存储(通常是固态硬盘或网络存储)和网络带宽,为了达到最高效率可以并行使用它们。
  • 后端可以通过自动化地并行计算和通信来提高性能。

练习

  1. 在本节定义的run函数中执行了八个操作,并且操作之间没有依赖关系。设计一个实验,看看深度学习框架是否会自动地并行地执行它们。

解:
run函数实际是执行了50个矩阵乘法操作,设计实验比较单个矩阵乘法和用run函数执行50个矩阵乘法的时间,发现用run函数执行50个矩阵乘法的时间小于单个矩阵乘法执行50次的时间,证明深度学习框架会自动地并行地执行它们。
代码如下:

# 单个矩阵乘法时间基准
with d2l.Benchmark('Single matmul'):x_gpu1.mm(x_gpu1)torch.cuda.synchronize()# 多个独立矩阵乘法时间
with d2l.Benchmark('Multiple matmuls'):run(x_gpu1)torch.cuda.synchronize()

输出结果:
Single matmul: 0.0457 sec
Multiple matmuls: 1.4930 sec

2. 当单个操作符的工作量足够小,即使在单个CPU或GPU上,并行化也会有所帮助。设计一个实验来验证这一点。

解:
还是基于矩阵乘法,将x的尺寸设置为10×10的小尺寸,在单个CPU或GPU上,用run函数自动并行的计算时间都更少,说明当单个操作符的工作量足够小,即使在单个CPU或GPU上,并行化也会有所帮助。
代码如下:

def benchmark_matmul(size, device):x = torch.randn(size, size, device=device)# 顺序执行基准with d2l.Benchmark(f'Size {size}x{size} (Sequential)'):for _ in range(50):_ = x.matmul(x)if device.type == 'cuda': torch.cuda.synchronize()# 自动并行执行(框架隐式优化)with d2l.Benchmark(f'Size {size}x{size} (Auto-Parallel)'):run(x)if device.type == 'cuda':torch.cuda.synchronize()
# 单个CPU
device = torch.device('cpu')
benchmark_matmul(10, device)

输出结果:
Size 10x10 (Sequential): 0.0518 sec
Size 10x10 (Auto-Parallel): 0.0005 sec

# 单个GPU
devices = d2l.try_all_gpus()
benchmark_matmul(10, devices[0])

输出结果:
Size 10x10 (Sequential): 0.0025 sec
Size 10x10 (Auto-Parallel): 0.0010 sec

3. 设计一个实验,在CPU和GPU这两种设备上使用并行计算和通信。

解:
本节的12.3.2中的实验可以说明,在CPU和GPU这两种设备上可以同时进行并行计算和通信,减少总体运行时间。

4. 使用诸如NVIDIA的Nsight之类的调试器来验证代码是否有效。

解:
没有Nsight,改用Pytorch的Profiler验证,从Profiler打印的结果表格中可以看到,多个任务的Self CUDA %都是100%,说明确实进行了并行计算。
代码如下:

from torch.profiler import ProfilerActivitywith torch.profiler.profile(activities=[ProfilerActivity.CUDA, ProfilerActivity.CPU],schedule=torch.profiler.schedule(wait=1, warmup=1, active=3),on_trace_ready=torch.profiler.tensorboard_trace_handler('./log')
) as prof:for _ in range(5):run(x_gpu1)run(x_gpu2)torch.cuda.synchronize()prof.step()
print(prof.key_averages().table()
输出结果:
-------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  Name    Self CPU %      Self CPU   CPU total %     CPU total  CPU time avg     Self CUDA   Self CUDA %    CUDA total  CUDA time avg    # of Calls  
-------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ProfilerStep*         0.04%       1.745ms       100.00%        4.440s        1.480s       0.000us         0.00%        8.837s        2.946s             3  aten::mm         0.13%       5.705ms         0.17%       7.698ms      25.659us        8.837s       100.00%        8.837s      29.458ms           300  cudaOccupancyMaxActiveBlocksPerMultiprocessor         0.00%     202.240us         0.00%     202.240us       0.674us       0.000us         0.00%       0.000us       0.000us           300  cudaLaunchKernel         0.04%       1.790ms         0.04%       1.790ms       5.968us       0.000us         0.00%       0.000us       0.000us           300  ProfilerStep*         0.00%       0.000us         0.00%       0.000us       0.000us        8.838s       100.00%        8.838s        1.473s             6  volta_sgemm_128x64_nn         0.00%       0.000us         0.00%       0.000us       0.000us        8.837s       100.00%        8.837s      29.755ms           297  cudaDeviceSynchronize        99.79%        4.430s        99.79%        4.430s        1.108s       0.000us         0.00%       0.000us       0.000us             4  
-------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  
Self CPU time total: 4.440s
Self CUDA time total: 8.837s

5. 设计并实验具有更加复杂的数据依赖关系的计算任务,以查看是否可以在提高性能的同时获得正确的结果。

解:
以下实验可以证明,在利用并行提高计算性能的同时,获得与串行一致的结果。
代码如下:

# 构建复杂依赖关系:
#   A → B → C
#   │    │
#   ↓    ↓
#   D → E → Fimport timedef task(x, name):"""模拟不同计算任务"""if name == 'A': return x @ x.Telif name == 'B': return x * x.sum()elif name == 'C': return x.cos() + x.sin()elif name == 'D': return x.pow(2).mean()elif name == 'E': return x.norm(dim=1)elif name == 'F': return x.softmax(dim=0)def serial_execution(x):"""串行执行(严格按依赖顺序)"""a = task(x, 'A')b = task(a, 'B')d = task(a, 'D')c = task(b, 'C')e = task(b, 'E')f = task(e, 'F')return c, d, fdef parallel_execution(x):"""并行执行(重叠无依赖任务)"""# 第一层并行stream1 = torch.cuda.Stream()stream2 = torch.cuda.Stream()with torch.cuda.stream(stream1):a = task(x, 'A')torch.cuda.synchronize()  # 确保a完成with torch.cuda.stream(stream1):b = task(a, 'B')with torch.cuda.stream(stream2):d = task(a, 'D')  # 与b无依赖,可并行torch.cuda.synchronize()  # 等待b,d完成with torch.cuda.stream(stream1):c = task(b, 'C')with torch.cuda.stream(stream2):e = task(b, 'E')  # 依赖b,但c/e之间无依赖torch.cuda.synchronize()  # 等待e完成f = task(e, 'F')return c, d, f
def run_test(matrix_size=1000):x = torch.randn(matrix_size, matrix_size, device='cuda')# 串行执行torch.cuda.synchronize()start = time.time()c_serial, d_serial, f_serial = serial_execution(x)torch.cuda.synchronize()serial_time = time.time() - start# 并行执行torch.cuda.synchronize()start = time.time()c_parallel, d_parallel, f_parallel = parallel_execution(x)torch.cuda.synchronize()parallel_time = time.time() - start# 结果对比def check_equal(t1, t2):return torch.allclose(t1, t2, rtol=1e-4, atol=1e-6)is_correct = (check_equal(c_serial, c_parallel) and check_equal(d_serial, d_parallel) and check_equal(f_serial, f_parallel))print(f"矩阵大小: {matrix_size}x{matrix_size}")print(f"串行时间: {serial_time:.4f}s")print(f"并行时间: {parallel_time:.4f}s")print(f"加速比: {serial_time/parallel_time:.2f}x")print(f"结果一致: {is_correct}")
run_test(matrix_size=1000)

输出结果:
矩阵大小: 1000x1000
串行时间: 0.3834s
并行时间: 0.0062s
加速比: 61.86x
结果一致: True

相关文章:

动手学深度学习12.3.自动并行-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:无 本节教材地址:12.3. 自动并行 — 动手学深度学习 2.0.0 documentation 本节开源代…...

第二十二天打卡

数据预处理 import pandas as pd from sklearn.model_selection import train_test_splitdef data_preprocessing(file_path):"""泰坦尼克号生存预测数据预处理函数参数:file_path: 原始数据文件路径返回:preprocessed_data: 预处理后的数据集""&quo…...

SET NX互斥功能的实现原理

Redis 的 SET key value NX 命令通过其原子性和底层数据结构的特性实现互斥功能,具体实现如下: 1. 互斥功能的实现原理 SET NX 的核心是 原子性操作:当且仅当键(key)不存在时,才会设置键的值。Redis 的单线…...

前端 CSS 样式书写与选择器 基础知识

1.CSS介绍 CSS是Cascading Style Sheet的缩写,中文意思为"层叠样式表",它是网页的装饰者,用来修饰各标签 排版(大小、边距、背景、位置等)、改变字体的样式(字体大小、字体颜色、对齐方式等)。 2.CSS书写位置 2.1 样式表特征 层…...

一小时学会Docker使用!

文章目录 前言一、安装ssh连接工具二、安装docker三、Docker常见命令四、docker-compose使用 前言 Docker: Docker简单来说就是简化环境配置的,我们配置环境只需要简单的docker pull,docker run即可,而删除环境也很容易&#xff…...

android studio开发aar插件,并用uniapp开发APP使用这个aar

android studio开发aar插件,并用uniapp开发APP使用这个aar 使用android studio打包aar和Unity导入aar详解...

操作系统实战——QEMU模拟器搭建【rCore 操作系统】

操作系统大作业——QEMU模拟器搭建rCore操作系统 按照本篇步骤走,帮你少走很多弯路!博主在自己做的过程中踩了很多坑,过程还是很痛苦的,走了很多弯路,现在都已经在文章中把坑填平了,把弯路修直了。 创作不易…...

web:InfiniteScroll 无限滚动

InfiniteScroll 无限滚动 分页加载 <div class"data-box" v-infinite-scroll"loadMore"> <li v-fori in dataList></li> </div>form: {current: 1,size: 10,}loadMore(){console.log(this.dataList.length, this.total ,8888)if…...

【Redis 进阶】哨兵模式

思维导图&#xff1a; 一、哨兵模式概述 &#xff08;一&#xff09;传统主从复制模式的局限性 在传统的Redis主从复制架构中&#xff0c;若主节点发生故障&#xff0c;运维人员需手动执行故障转移操作&#xff0c;将一个从节点提升为新主节点&#xff0c;并逐一通知所有客户…...

告别卡顿,图片查看界的“速度与激情”

嘿&#xff0c;小伙伴们&#xff01;今天电脑天空给大家介绍一款超好用的图片查看神器——ImageGlass&#xff01;这可不是普通的图片查看软件哦&#xff0c;它简直就是图片界的“全能王”。首先&#xff0c;它能打开的图片格式多到让你眼花缭乱&#xff0c;什么PNG、JPEG、GIF…...

02_线性模型(回归分类模型)

用于分类的线性模型 线性模型也广泛应用于分类问题&#xff0c;可以利用下面的公式进行预测&#xff1a; $ \widehat y w[0]*x[0]w[1]*x[1]…w[p]*x[p]b > 0$ 公式看起来与线性回归的公式非常相似&#xff0c;但没有返回特征的加权求和&#xff0c;而是为预测设置了阈值…...

力扣2094题解

记录&#xff1a; 2025.5.12 题目&#xff1a; 思路&#xff1a; 暴力遍历。 解题步骤&#xff1a; 1.统计数字出现次数&#xff1a;使用数组cnt来记录输入数组中每个数字的出现次数。 2.生成三位偶数&#xff1a;通过循环从100开始&#xff0c;每次递增2&#xff0c;生成…...

人物角色设定机制

模块一&#xff1a;角色塑造进阶技巧 将角色设定(Character Headcanon)提升至更高层次 当您通过Character Headcanon Generator生成基础设定后&#xff0c;可运用以下专业技巧深化角色塑造&#xff1a; 情感核心图谱分析法 解构角色情感驱动机制及其情境表现&#xff1a; 主…...

Python动态渲染页面抓取之Selenium使用指南

目录 一、Selenium技术架构解析 二、环境搭建与基础配置 1. 组件安装 2. 驱动配置 3. 基础操作模板 三、动态内容抓取核心策略 1. 智能等待机制 2. 交互行为模拟 3. 反爬应对方案 四、实战案例&#xff1a;电商评论抓取 五、性能优化与异常处理 2. 异常捕获 六、进…...

智能手表 MCU 任务调度图

智能手表 MCU 任务调度图 处理器平台&#xff1a;ARM Cortex-M33 系统架构&#xff1a;事件驱动 多任务 RTOS RTOS&#xff1a;FreeRTOS&#xff08;或同类实时内核&#xff09; 一、任务调度概览 任务名称优先级周期性功能描述App_MainTask中否主循环调度器&#xff0c;系统…...

【C++】cout的格式输出

目录 一、cout的格式输出1、控制宽度和填充2、控制数值格式3、控制整数格式4、控制对齐方式 个人主页<—请点击 C专栏<—请点击 一、cout的格式输出 printf函数在输出数据的时候&#xff0c;可以指定格式来输出&#xff0c;比如&#xff1a;指定宽度、指定小数点后的位…...

私域流量新阵地:掌握Telegram私域运营全方法

在流量获取成本不断上升的今天&#xff0c;越来越多企业和品牌开始将目光转向“私域流量”——一条可以长期沉淀用户、反复转化的可持续增长之路。而在全球化趋势下&#xff0c;Telegram作为一款以高自由度、强隐私性著称的即时通讯平台&#xff0c;正在成为私域运营的新阵地。…...

Python Day23 学习

继续SHAP图绘制的学习 1. SHAP特征重要性条形图 特征重要性条形图&#xff08;Feature Importance Bar Plot&#xff09;是 SHAP 提供的一种全局解释工具&#xff0c;用于展示模型中各个特征对预测结果的重要性。以下是详细解释&#xff1a; 图的含义 - 横轴&#xff1a;表示…...

《ATPL地面培训教材13:飞行原理》——第12章:飞行力学基础

翻译&#xff1a;Leweslyh&#xff1b;工具&#xff1a;Cursor & Cluade 3.7&#xff1b;过程稿 第12章&#xff1a;飞行力学基础 目录 引言直线水平稳定飞行尾翼和升降舵直线稳定爬升爬升角重量、高度和温度的影响带动力下降紧急下降滑翔滑翔下降率转弯非对称推力飞行最…...

数据中台整体建设方案规划设计方案,数据中台建设汇报方案(PPT)

中台建设背景 在数字化转型浪潮下&#xff0c;企业需通过客户需求精准化、营销策略智能化、管理体系数字化三大核心方向构建竞争优势。本项目以渠道数据整合为基础&#xff0c;围绕客户精准化运营、营销智能化决策、管理数字化赋能三大目标&#xff0c;打造支撑一线业务场景的数…...

嵌入式软件--stm32 DAY 6 USART串口通讯(下)

1.寄存器轮询_收发字符串 通过寄存器轮询方式实现了收发单个字节之后&#xff0c;我们趁热打铁&#xff0c;争上游&#xff0c;进阶到字符串。字符串就是多个字符。很明显可以循环收发单个字节实现。 然后就是接收字符串。如果接受单个字符的函数放在while里&#xff0c;它也可…...

Flask如何读取配置信息

目录 一、使用 app.config 读取配置 二、设置配置的几种方式 1. 直接设置 2. 从 Python 文件加载 3. 从环境变量加载 4. 从字典加载 5. 从 .env 文件加载&#xff08;推荐开发环境用&#xff09; 三、读取配置值 四、最佳实践建议 在 Flask 中读取配置信息有几种常见方…...

AWS EC2源代码安装valkey命令行客户端

sudo yum -y install openssl-devel gcc wget https://github.com/valkey-io/valkey/archive/refs/tags/8.1.1.tar.gz tar xvzf 8.1.1.tar.gz cd valkey-8.1.1/ make distclean make valkey-cli BUILD_TLSyes参考 Connecting to nodes...

项目全栈实战-基于智能体、工作流、API模块化Docker集成的创业分析平台

目录 思维导图 前置知识 Docker是什么&#xff1f; Docker的核心概念&#xff1a; Docker在本项目中的作用 1. 环境隔离与一致性 2. 简化部署流程 3. 资源管理与扩展性 4. 服务整合与通信 5. 版本控制和回滚 6. 开发与生产环境一致性 总结 前端 1.小程序 2.web …...

如何快速入门大模型?

学习大模型的流程是什么 &#xff1f; 提示词工程&#xff1a;只需掌握提问技巧即可使用大模型&#xff0c;通过优化提问方式获得更精准的模型输出套壳应用开发&#xff1a;在大模型生态上开发业务层产品&#xff08;如AI主播、AI小助手等&#xff09;&#xff0c;只需调用API…...

《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》

暗黑模式已从一种新奇的功能演变为用户体验中不可或缺的一环。对于Flutter开发者而言&#xff0c;如何在社交应用中完美实现暗黑模式适配与色彩对比度优化&#xff0c;是一场充满挑战与惊喜的技术探索之旅。 暗黑模式&#xff0c;绝非仅仅是将界面颜色反转这么简单。从用户体验…...

【秣厉科技】LabVIEW工具包——OpenCV 教程(21):CUDA 加速方案

文章目录 前言一、方案总述二、改造步骤三、编程范例四、应用移植总结 前言 需要下载安装OpenCV工具包的朋友&#xff0c;请前往 此处 &#xff1b;系统要求&#xff1a;Windows系统&#xff0c;LabVIEW>2018&#xff0c;兼容32位和64位。 一、方案总述 为了保持轻量化与普…...

flutter使用命令生成BinarySize分析图

flutter build ios --analyze-size 生成的文件&#xff0c;使用dev tools 可以分析具体的包大小...

高并发场景下的BI架构设计:衡石分布式查询引擎与缓存分级策略

在电商大促、金融交易时段或IoT实时监控场景中&#xff0c;企业BI系统常面临瞬时万级并发查询的冲击——运营团队需要实时追踪GMV波动&#xff0c;风控部门需秒级响应欺诈检测&#xff0c;产线监控需毫秒级反馈设备状态。传统单体架构的BI系统在此类场景下极易崩溃&#xff0c;…...

web 自动化之 selenium 下拉鼠标键盘文件上传

文章目录 一、下拉框操作二、键盘操作三、鼠标操作四、日期控件五、滚动条操作六、文件上传七、定位windows窗口及窗口的元素总结&#xff1a;页面及元素常用操作 一、下拉框操作 from selenium.webdriver.support.select import Select import time from selenium.webdriver.…...

Qt Creator 配置 Android 编译环境

Qt Creator 配置 Android 编译环境 环境配置流程下载JDK修改Qt Creator默认android配置文件修改sdk_definitions.json配置修改的内容 Qt Creator配置异常处理删除提示占用编译报错 环境 Qt Creator 版本 qtcreator-16.0.1Win10 嗯, Qt这个开发环境有点难折腾,搞了我三天… 配…...

主流编程语言中ORM工具全解析

在不同编程语言中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;工具的设计目标都是简化数据库操作。 以下是主流语言中最常用的 ORM 工具&#xff0c;按语言分类介绍其特点、适用场景和典型案例。 一、Python 生态 Python 社区…...

详解RabbitMQ工作模式之发布确认模式

​​​​​​​ 目录 发布确认模式 概述 消息丢失问题 发布确认的三种模式 实现步骤 应用场景 代码案例 引入依赖 常量类 单条确认 运行代码 批量确认 运行代码 异步确认 运行代码 对比批量确认和异步确认模式 发布确认模式 概述 发布确认模式用于确保消息已…...

Power BI 实操案例,将度量值转化为切片器(动态切换分析指标)

Power BI 实操案例&#xff0c;将度量值转化为切片器&#xff08;动态切换分析指标&#xff09; 想要在Power BI中让度量值也能像维度一样灵活筛选&#xff1f;没问题&#xff0c;这里就为你揭秘如何将度量值转化为切片器&#xff08;动态切换分析指标&#xff09;的实用方法&…...

利用散点图探索宇航员特征与太空任务之间的关系

利用散点图探索宇航员特征与太空任务之间的关系 import matplotlib.pyplot as plt import numpy as np import pandas as pdfrom flexitext import flexitext from matplotlib.patches import FancyArrowPatchplt.rcParams.update({"font.family": "Corbel&quo…...

人工智能的哲学与社会影响

人工智能&#xff08;AI&#xff09;的快速发展对人类社会的方方面面产生了深远的影响。在这部分中&#xff0c;我们将探讨AI对人与机器关系的影响、AI对就业和经济的潜在影响&#xff0c;以及人类与AI共存的可能性和道德议题。同时&#xff0c;我们还将针对大众对AI的一些常见…...

MySQL 中 UPDATE 结合 SELECT 和 UPDATE CASE WHEN 的示例

概述 以下是 MySQL 中 UPDATE 结合 SELECT 和 UPDATE CASE WHEN 的示例&#xff1a; 一、UPDATE 结合 SELECT&#xff08;跨表更新&#xff09; 场景&#xff1a;根据 orders 表中的订单总金额&#xff0c;更新 users 表中用户的 total_spent 字段。 -- 创建测试表 CREATE T…...

FPGA前瞻篇-计数器设计与实现实例

这是本篇文章的设计目标如下所示&#xff1a; 这个 Counter 模块是一个LED 闪烁计数器&#xff0c;设计目标是&#xff1a; 当输入时钟 clk 为 50 MHz 时&#xff0c;每 0.5 秒翻转一次 LED 灯状态。 随后我们开始补充理论知识。 计数是一种最简单基本的运算&#xff0c;计数器…...

运行Spark程序-在Idea中(二)

&#xff08;四&#xff09;使用Maven创建新项目 核心的操作步骤如下&#xff1a; 1.启动idea,选择新建项目。 2.将Scala添加到全局库中。 3.设置maven依赖项。修改pom.xml文件&#xff0c;添加如下&#xff1a; 4.下载依赖。添加完成之后&#xff0c;刷新Maven&#xff0c;它…...

Mosaic数据增强技术

Mosaic 数据增强技术是一种在计算机视觉领域广泛应用的数据增强方法。下面是Mosaic 数据增强技术原理的详细介绍 一、原理 Mosaic 数据增强是将多张图像&#xff08;通常是 4 张&#xff09;按照一定的规则拼接在一起&#xff0c;形成一张新的图像。在拼接过程中&#xff0c;会…...

Kafka、RabbitMQ 和 RocketMQ区别及上手难度

Kafka、RabbitMQ 和 RocketMQ 是三种流行的消息中间件&#xff0c;它们在设计理念、使用场景和上手难度上有显著差异。以下是它们的核心区别和上手难度分析&#xff1a; 1. 核心区别 特性KafkaRabbitMQRocketMQ设计目标高吞吐、分布式日志流处理通用的消息队列&#xff0c;强调…...

.NET 8 + Angular WebSocket 高并发性能优化

.NET 8 Angular WebSocket 高并发性能优化。 .NET 8 WebSocket 高并发性能优化 WebSocket 是一种全双工通信协议&#xff0c;允许客户端和服务端之间保持持久连接。在高并发场景下&#xff0c;优化 WebSocket 的性能至关重要。以下是针对 .NET 8 中 WebSocket 高并发性能优化…...

SimScape物理建模实例1--单质量-弹簧-阻尼系统

实例1模型下载&#xff1a; 【免费】simscape单质量弹簧阻尼模型资源-CSDN文库 如下图所示单质量弹簧阻尼系统&#xff0c;弹簧具有初始压缩量&#xff0c;假设为1m, 质量块除了受到自身重力作用以外&#xff0c;受到弹簧拉力&#xff0c;以及阻尼器阻尼力&#xff0c;根据牛顿…...

5.5.1 WPF中的动画2-基于路径的动画

何为动画?一般只会动。但所谓会动,还不仅包括位置移动,还包括角度旋转,颜色变化,透明度增减。动画本质上是一个时间段内某个属性值(位置、颜色等)的变化。因为属性有很多数据类型,它们变化也需要多种动画类比如: BooleanAnimationBase\ ByteAnimationBase\DoubleAnima…...

JVM对象分配与程序崩溃排查

一、new 对象在 JVM 中的过程 在 JVM 中通过 new 关键字创建对象时&#xff0c;会经历以下步骤&#xff1a; 内存分配 对象的内存分配在 堆&#xff08;Heap&#xff09; 中&#xff0c;优先在 新生代&#xff08;Young Generation&#xff09; 的 Eden 区 分配。分配方式取决…...

基于RT-Thread驱动EEPROM_AD24C02

基于RT-Thread驱动EEPROM_AD24C02 前言一、硬件设计二、软件设计三、测试1、eeprom_test&#xff08;&#xff09;测试2、基础操作字节实验3、多字节读写 前言 存储容量2048位&#xff0c;内部组织256x8&#xff08;2K&#xff09;&#xff0c;即256个字节的存储单元&#xff…...

VUE中通过DOM导出PDF

最终效果 前端导出PDF的核心在于样式的绘制上&#xff0c;这里其实直接使用CSS进行绘制和布局就行&#xff0c;只不过需要计算好每页DIV盒子的大小&#xff0c;防止一页放不下造成样式错乱。 项目依赖 项目是Vue3 TS npm i html2canvas1.4.1 npm i jspdf3.0.1工具类(htmlToPdf…...

sql语句面经手撕(定制整理版)

一张表 店铺id 商品id 销售数量 问&#xff1a;查询总销售数量最多的店铺 SELECT shop_id,SUM(quantity) AS total_quantity FROM sales GROUP BY shop_id ORDER BY total_quantity DESC LIMIT 1; 学生总分名最高的 SELECT student_id,SUM(score) AS total_score FROM score…...

pdf 不是扫描件,但却无法搜索关键词【问题尝试解决未果记录】

一、不是扫描件但不能搜索的原因 1. 情况一&#xff1a;文字被转成了“图形文字” 有些PDF文件虽然看起来像是文字&#xff0c;其实是图片或者矢量图格式&#xff0c;不能直接搜索。 2. 情况二&#xff1a;PDF被加密 有些PDF设置了“内容复制/提取”权限受限&#xff0c;即使…...

android14优化ntp时间同步

简介 网络时间协议NTP&#xff08;Network Time Protocol&#xff09;是TCP/IP协议族里面的一个应用层协议&#xff0c;用来使客户端和服务器之间进行时钟同步&#xff0c;提供高精准度的时间校正。 当机器的ntp时间同步出现问题时&#xff0c;可以从ntp配置方面进行优化&…...