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

汽车长翅膀:GPU 是如何加速深度学习模型的训练和推理过程的?

编者按:深度学习的飞速发展离不开硬件技术的突破,而 GPU 的崛起无疑是其中最大的推力之一。但你是否曾好奇过,为何一行简单的“.to(‘cuda’)”代码就能让模型的训练速度突飞猛进?本文正是为解答这个疑问而作。

作者以独特的视角,将复杂的 GPU 并行计算原理转化为通俗易懂的概念。从 CPU 与 GPU 的设计哲学对比,到 CUDA 编程的核心要素,再到具体的代码实现,文章循序渐进地引领读者把握 GPU 并行计算的精髓。特别是文中巧妙的比喻 —— 将 CPU 比作法拉利,GPU 比作公交车,这一比喻生动形象地诠释了两种处理器的特性。

这篇文章不仅回答了"为什么",更指明了"如何做",在当前人工智能技术飞速发展的背景下,理解底层技术原理的重要性不言而喻。这篇文章虽为入门级别的技术内容介绍,但也提到了更高级的优化技术和工具库,指明了进一步的学习方向,具有一定的学习和参考价值。

作者 | Lucas de Lima Nogueira

编译 | 岳扬

Image by the author with the assistance of AI (https://copilot.microsoft.com/images/create)

现如今,当我们提及深度学习时,人们自然而然地会联想到通过 GPU 来增强其性能。

GPU(图形处理器,Graphical Processing Units)起初是为了加速图像(images)及 2D、3D 图形(graphics)的渲染而生。但凭借其强大的并行运算能力,GPU 的应用范围迅速拓展,已扩展至深度学习(deep learning)等应用领域。

GPU 在深度学习模型中的应用始于 2000 年代中后期,2012 年 AlexNet 的横空出世更是将这种趋势推向高潮。 AlexNet,这款由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 共同设计、研发的卷积神经网络,在 2012 年的 ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 上一鸣惊人。这一胜利具有里程碑式的意义,它不仅证实了深度神经网络在图像分类领域(image classification)的卓越性能,同时也彰显了使用 GPU 训练大型模型的有效性。

在这一技术突破之后,GPU 在深度学习模型中的应用愈发广泛,PyTorch 和 TensorFlow 等框架应运而生。

如今,我们只需在 PyTorch 中轻敲 .to(“cuda”),即可将数据传递给 GPU,从而加速模型的训练。但在实践中,深度学习算法究竟是如何巧妙地利用 GPU 算力的呢?让我们一探究竟吧!

深度学习的核心架构,如神经网络、CNNs、RNNs 和 transformer,其本质都围绕着矩阵加法(matrix addition)、矩阵乘法(matrix multiplication)以及对矩阵应用函数(applying a function a matrix)等基本数学操作展开。因此,优化这些核心运算,便是提升深度学习模型性能的关键所在。

那么,让我们从最基础的场景说起。想象一下,你需要对两个向量执行相加操作 C = A + B。

可以用 C 语言简单实现这一功能:

不难发现,传统上,计算机需逐一访问向量中的各个元素(elements),在每次迭代中按顺序对每对元素进行加法运算。但有一点需要注意,各对元素间的加法操作互不影响,即任意一对元素的加法不依赖于其它任何一对。那么,若我们能同时执行这些数学运算,实现所有元素对(pairs of elements)的并行相加,效果会如何呢?

直接做法是借助 CPU 的多线程功能,并行执行所有数学运算。但在深度学习领域,我们需要处理的向量规模巨大,往往包含数百万个元素。通常情况下,普通 CPU 只能同时处理十几条线程。此时,GPU 的优势便凸显出来!目前的主流 GPU 能够同时运行数百万个线程,极大地提高了处理大规模向量中数学运算的效率。

01 GPU vs. CPU comparison

虽然从单次运算(single operation)的处理速度来看,CPU 或许略胜 GPU 一筹,但 GPU 的优势在于其卓越的并行处理能力。究其根源,这一情况源于两者设计初衷的差异。CPU 的设计侧重于高效执行单一序列的操作(即线程(thread)),但一次仅能同时处理几十个;相比之下,GPU 的设计目标是实现数百万个线程的并行运算,虽有所牺牲单个线程的运算速度,却在整体并行性能上实现了质的飞跃。

打个比方,你可以将 CPU 视作一辆炫酷的法拉利(Ferrari)跑车,而 GPU 则如同一辆宽敞的公交车。倘若你的任务仅仅是运送一位乘客,毫无疑问,法拉利(CPU)是最佳选择。然而,如若当前的运输需求是运送多位乘客,即使法拉利(CPU)单程速度占优,公交车(GPU)却能一次容纳全部乘客,其集体运输效率远超法拉利多次单独接送的效率。由此可见,CPU 更适于处理连续性的单一任务,而 GPU 则在并行处理大量任务时展现出色的效能。

Image by the author with the assistance of AI (https://copilot.microsoft.com/images/create)

为了实现更出色的并行计算能力,GPU 在设计上倾向于将更多晶体管资源(transistors)投入到数据处理中,而非数据缓存(data caching)和流控机制(flow contro),这与 CPU 的设计思路大相径庭。CPU 为了优化单一线程的执行效率和复杂指令集的处理,特意划拨了大量的晶体管来加强这些方面的性能。

下图生动地描绘了 CPU 与 GPU 在芯片资源分配上的显著差异。

Image by the author with inspiration from CUDA C++ Programming Guide

(https://docs.nvidia.com/cuda/pdf/CUDA_C_Programming_Guide.pdf)

CPU 配备了高性能内核(powerful cores)与更为精妙的缓存内存架构(cache memory architecture)(消耗了相当多的晶体管资源),这种设计方案能够极大地优化顺序任务的执行速度。而图形处理器(GPU)则着重于内核(cores)数量,以实现更高的并行处理能力。

现在已经介绍完这些基础知识,那么在实际应用中,我们应如何有效利用并行计算的优势呢?

02 Introduction to CUDA

当我们着手构建深度学习模型时,很可能会倾向于采用诸如 PyTorch 或 TensorFlow 这类广受欢迎的 Python 开发库。尽管如此,一个不争的事实是,这些库的核心代码都是 C/C++ 代码。另外,正如我们先前所提及的,利用 GPU 加快数据的处理速度往往是一种主流优化方案。此时,CUDA 的重要作用便凸显出来!CUDA 是统一计算设备架构(Compute Unified Device Architecture)的缩写,是英伟达(NVIDIA)为使 GPU 能够在通用计算领域大放光彩而精心打造的平台。与 DirectX 被游戏引擎用于图形运算(graphical computation)不同,CUDA 使开发人员能够将英伟达(NVIDIA)的 GPU 计算能力集成到通用软件中,而不仅仅局限于图形渲染。

为了实现这一目标,CUDA 推出了一款基于 C/C++ 的简易接口(CUDA C/C++),帮助开发者调用 GPU 虚拟指令集(virtual intruction se)及执行特定操作(specific operations)(如在 CPU 与 GPU 间传输数据)。

在继续深入技术细节之前,我们有必要澄清几个 CUDA 编程的基础概念和专业术语:

  • host:特指 CPU 及其配套内存;
  • device:对应 GPU 及其专属内存;
  • kernel:指代在设备(GPU)上运行的函数代码;

因此,在一份使用 CUDA 撰写的基本代码(basic code)中,程序主体在 host (CPU) 上执行,随后将数据传递给 device (GPU) ,并调用 kernels (functions) 在 device (GPU) 上并行运行。这些 kernels 由多条线程同时执行。运算完成后,结果再从 device (GPU) 回传至 host (CPU) 。

话说回来,让我们再次聚焦于两组向量相加这个具体问题:

借助 CUDA C/C++,编程人员能够创建一种被称为 kernels 的 C/C++ 函数;一旦这些 kernels 被调用, N 个不同的 CUDA 线程会并行执行 N 次。

若想定义这类 kernel,可运用 __global__ 关键字作为声明限定符(declaration specifier),而若欲设定执行该 kernel 的具体 CUDA 线程数目,则需采用 <<<...>>> 来完成:

每个 CUDA 线程在执行 kernel 时,都会被赋予一个独一无二的线程 ID,即 threadIdx,它可以通过 kernel 中的预设变量获取。上述示例代码将两个长度(size)均为 N 的向量 A 和 B 相加,并将结果保存到向量 C 中。值得我们注意的是,相较于循环逐次处理成对加法的传统串行方式,CUDA 的优势在于其能够并行利用 N 个线程,一次性完成全部加法运算。

不过,在运行上述这段代码前,我们还需对其进行一次修改。切记,kernel 函数的运行环境是 device (GPU) ,这意味着所有相关数据均须驻留于 device 的内存之中。 要达到这一要求,可以借助 CUDA 提供的以下内置函数:

直接将变量 A、B 和 C 传入 kernel 的做法并不适用于本情况,我们应当使用指针。在 CUDA 编程环境下,host 数组(比如示例中的 A、B 和 C)无法直接用于 kernel 启动(<<<…>>>)。鉴于 CUDA kernels 的工作空间为 device 的内存(device memory),故需向 kernel 提供 device 指针(device pointers)(d_A、d_B 和 d_C),以确保其能在 device 的内存上运行。

除此之外,我们还需通过调用 cudaMalloc 函数在 device 上划分内存空间,并运用 cudaMemcpy 实现 host 和 device 之间的数据传输。

至此,我们可在代码中实现向量 A 和 B 的初始化,并在程序结尾处清理 CUDA 内存(cuda memory)。

另外,调用 kernel 后,务必插入 cudaDeviceSynchronize(); 这一行代码。该函数的作用在于协调 host 线程与 device 间的同步,确保 host 线程在继续执行前,device 已完成所有先前提交的 CUDA 操作。

此外,CUDA 的错误检测机制同样不可或缺,这种检测机制能协助我们及时发现并修正 GPU 上潜在的程序缺陷(bugs)。倘若忽略此环节,device 线程(CPU)将持续运行,而 CUDA 相关的故障排查则将变得异常棘手,很难识别与 CUDA 相关的错误。

下面是这两种技术的具体实现方式:

要编译和运行 CUDA 代码,首先需要确保系统中已装有 CUDA 工具包(CUDA toolkit)。紧接着,使用 nvcc —— NVIDIA CUDA 编译器完成相关代码编译工作。

然而,当前的代码尚存优化空间。在前述示例中,我们处理的向量规模仅为 N = 1000,这一数值偏小,难以充分展示 GPU 强大的并行处理能力。特别是在深度学习场景下,我们时常要应对含有数以百万计参数的巨型向量。然而,倘若尝试将 N 的数值设为 500000,并采用 <<<1, 500000>>> 的方式运行 kernel ,上述代码便会抛出错误。因此,为了完善代码,使之能顺利执行此类大规模运算,我们亟需掌握 CUDA 编程中的核心理念 —— 线程层级结构(Thread hierarchy)。

03 Thread hierarchy(线程层级结构)

调用 kernel 函数时,采用的是 <<<number_of_blocks, threads_per_block>>> 这种格式(notation)。因此,在上述示例中,我们是以单个线程块的形式,启动了 N 个 CUDA 线程。然而,每个线程块所能容纳的线程数量都有限制,这是因为所有处于同一线程块内的线程,都被要求共存于同一流式多处理器核心(streaming multiprocessor core),并共同使用该核心的内存资源。

欲查询这一限制数量的具体数值,可通过以下代码实现:

就作者当前使用的 GPU 而言,其单一线程块最多能承载 1024 个线程。因此,为了有效处理示例中提及的巨型向量(massive vector),我们必须部署更多线程块,以实现更大规模的线程并发执行。 同时,这些线程块被精心布局成网格状结构(grids),如下图所展示:

https://handwiki.org/wiki/index.php?curid=1157670 (CC BY-SA 3.0)

现在,我们可以通过以下途径获取线程 ID:

于是,该代码脚本更新为:

04 性能对比分析

下表展示了在处理不同大小向量的加法运算时,CPU 与 GPU 的计算性能对比情况。

Image by the author

显而易见,GPU 的处理效能优势,唯有在处理大规模向量时方能得以凸显。此外,切勿忽视一件事,此处的时间对比仅仅考量了 kernel/function 的执行耗时,而未将 host 和 device 间数据传输所需的时间纳入考虑范围。尽管在大多数情况下,数据传输的时间开销微不足道,但就我们目前仅执行简易加法运算(simple addition operation)的情形而言,这部分时间消耗却显得相对可观。因此,我们应当铭记,GPU 的计算性能,仅在面对那些既高度依赖计算能力又适合大规模并行处理的任务时,才能得以淋漓尽致地展现。

05 多维线程处理(Multidimensional threads)

现在,我们已经知道如何提升简单数组操作(simple array operation)的性能了。然而,在处理深度学习模型时,必须要处理矩阵和张量运算(matrix and tensor operations)。在前文的示例中,我们仅使用了内含 N 个线程的一维线程块(one-dimensional blocks)。然而,执行多维线程块(multidimensional thread blocks)(最高支持三维)同样也是完全可行的。因此,为了方便起见,当我们需要处理矩阵运算时,可运行一个由 N x M 个线程组成的线程块。还可以通过 row = threadIdx.x 来确定矩阵的行索引,而 col = threadIdx.y 则可用来获取列索引。此外,为了简化操作,还可以使用 dim3 变量类型定义 number_of_blocks 和 threads_per_block。

下文的示例代码展示了如何实现两个矩阵的相加运算。

此外,我们还可以将此示例进一步拓展,实现对多个线程块的处理:

此外,我们也可以用同样的思路将这个示例扩展到三维运算(3-dimensional operations)操作的处理。

上文已经介绍了处理多维数据(multidimensional data)的方法,接下来,还有一个既重要又容易理解的概念值得我们学习:如何在 kernel 中调用 functions。 一般可以通过使用 __device__ 声明限定符(declaration specifier)来实现。这种限定符定义了可由 device (GPU)直接调用的函数(functions)。因此,这些函数仅能在 __global__ 或其他 __device__ 函数中被调用。下面这个示例展示了如何对一个向量进行 sigmoid 运算(这是深度学习模型中极其常见的一种运算方式)。

至此,我们已经掌握了 CUDA 编程的核心概念,现在可以着手构建 CUDA kernels 了。对于深度学习模型而言,其实质就是一系列涉及矩阵(matrix)与张量(tensor)的运算操作,包括但不限于求和(sum)、乘法(multiplication)、卷积(convolution)以及归一化(normalization )等。举个例子,一个基础的矩阵乘法算法,可以通过以下方式实现并行化:

我们可以注意到,在 GPU 版本的矩阵乘法算法中,循环次数明显减少,从而显著提升了运算处理速度。下面这张图表直观地展现了 N x N 矩阵乘法在 CPU 与 GPU 上的性能对比情况:

Image by the author

我们会发现,随着矩阵大小(matrix size)的增大,GPU 在处理矩阵乘法运算时的性能提升幅度更大。

接下来,让我们聚焦于一个基础的神经网络模型,其核心运算通常表现为 y = σ(Wx + b),如下图所示:

Image by the author

上述运算主要涉及矩阵乘法(matrix multiplication)、矩阵加法(matrix addition)以及对数组施加函数变换(applying a function to an array)。如若你已掌握这些并行化处理技术,意味着你现在完全具备了从零构建、并在 GPU 上构建神经网络的能力!

06 Conclusion

本文我们探讨了通过 GPU processing (译者注:使用 GPU进行数据处理和计算。)提升深度学习模型效能的入门概念。不过,有一点还需要指出,本文所介绍的内容仅仅是皮毛,背后还隐藏着很多很多更深层次的东西。PyTorch 和 Tensorflow 等框架实现了诸多高级性能优化技术,涵盖了 optimized memory access、batched operations 等复杂概念(其底层利用了基于 CUDA 的 cuBLAS 和 cuDNN 等库)。 但愿这篇文章能够让各位读者对使用 .to(“cuda”) 方法,在 GPU 上构建、运行深度学习模型时的底层原理,有个初步的了解。

Thanks so much for reading! 😊

Lucas de Lima Nogueira

https://www.linkedin.com/in/lucas-de-lima-nogueira/

END

原文链接:

https://towardsdatascience.com/why-deep-learning-models-run-faster-on-gpus-a-brief-introduction-to-cuda-programming-035272906d66

相关文章:

汽车长翅膀:GPU 是如何加速深度学习模型的训练和推理过程的?

编者按&#xff1a;深度学习的飞速发展离不开硬件技术的突破&#xff0c;而 GPU 的崛起无疑是其中最大的推力之一。但你是否曾好奇过&#xff0c;为何一行简单的“.to(‘cuda’)”代码就能让模型的训练速度突飞猛进&#xff1f;本文正是为解答这个疑问而作。 作者以独特的视角&…...

怀旧必玩!重返童年,扫雷游戏再度登场!

Python提供了一个标准的GUI&#xff08;图形用户界面&#xff09;工具包&#xff1a;Tkinter。它可以用来创建各种窗口、按钮、标签、文本框等图形界面组件。 而且Tkinter 是 Python 自带的库&#xff0c;无需额外安装。 Now&#xff0c;让我们一起来回味一下扫雷小游戏吧 扫…...

Avalonia中的路由事件

文章目录 一、路由事件的基本概念事件路由机制事件的生命周期二、创建路由事件定义路由事件触发路由事件处理路由事件三、使用路由事件的场景用户输入控件交互动画和样式数据绑定和验证四、路由事件的优缺点优点:缺点:五、总结在Avalonia中,路由事件是处理用户交互和控件之间…...

ubuntu20.04安装RabbitMQ +Erlang

ubuntu20.04安装RabbitMQ 3.11.19Erlang 25.3.1_ubuntu20.04.6 安装 rabbitmq-CSDN博客 LINUX下载编译libpng_linux libpng下载-CSDN博客 Ubuntu20.04 安装 Nginx 软件报错&#xff1a;libgd3 缺少 libpng12-0 依赖 Ubuntu安装RabbitMq&#xff08;保姆级教学&#xff0c;直…...

【word转pdf】【最新版本jar】Java使用aspose-words实现word文档转pdf

【aspose-words-22.12-jdk17.jar】word文档转pdf 前置工作1、下载依赖2、安装依赖到本地仓库 项目1、配置pom.xml2、配置许可码文件&#xff08;不配置会有水印&#xff09;3、工具类4、效果 踩坑1、pdf乱码2、word中带有图片转换 前置工作 1、下载依赖 通过百度网盘分享的文…...

分布式:RocketMQ/Kafka总结(附下载链接)

文章目录 下载链接思维导图 本文总结的是关于消息队列的常见知识总结。消息队列和分布式系统息息相关&#xff0c;因此这里就将消息队列放到分布式中一并进行处理关联 下载链接 链接: https://pan.baidu.com/s/1hRTh7rSesikisgRUO2GBpA?pwdutgp 提取码: utgp 思维导图...

Air780EP模块 LuatOS开发-MQTT接入阿里云应用指南

简介 本文简单讲述了利用LuatOS-Air进行二次开发&#xff0c;采用一型一密、一机一密两种方式认证方式连接阿里云。整体结构如图 关联文档和使用工具&#xff1a;LuatOS库阿里云平台 准备工作 Air780EP_全IO开发板一套&#xff0c;包括天线SIM卡&#xff0c;USB线 PC电脑&…...

【算法】插入区间

难度&#xff1a;中等 题目&#xff1a; 给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInte…...

C++ 代码实现socket 类使用TCP/IP进行通信 (windows 系统)

C 代码实现socket 类使用TCP/IP进行通信 &#xff08;windows 系统&#xff09; TCP客户端通信常规步骤&#xff1a; 1.初始换socket环境 2.socket()创建TCP套接字。 3.connect()建立到达服务器的连接。 4.与客户端进行通信&#xff0c;recv()/send()接受/发送信息&#xff0…...

前后端分离项目部署,vue--nagix发布部署,.net--API发布部署。

目录 Nginx免安装部署文件包准备一、vue前端部署1、修改http.js2、npm run build 编译项目3、解压Nginx免安装,修改nginx.conf二、.net后端发布部署1、编辑appsetting.json,配置跨域请求2、配置WebApi,点击发布3、配置文件发布到那个文件夹4、配置发布相关选项5、点击保存,…...

【BUG】已解决:UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10

UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10 目录 UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#x…...

C++ | QQ后端暑期实习面试

tcp三次握手&#xff0c;四次挥手 断点续传 文件断点续传是一种机制&#xff0c;允许在网络传输中的文件传输过程中出现断开连接或传输中断的情况下&#xff0c;能够恢复传输并继续传输未完成的部分。其原理如下&#xff1a; 检测支持&#xff1a;首先&#xff0c;服务器端和…...

实用网站推荐

​ 学习 前端 精简CSS格式 Font Awesome 图标库 BootCDN 加速服务 合集 AI工具集 动漫、音乐 娱乐 嗷呜动漫 奈飞同步 视频下载 B站视频解析下载 文件操作 ioDraw制作图 Convertio — 文件转换器 PDF处理 ​LOGO...

Linux |Nethogs 监控网络使用情况

引言 互联网上为 Linux 系统提供了许多开源的网络监控工具。例如&#xff0c;你可以利用 iftop 命令来监测网络带宽的消耗&#xff0c;使用 netstat 或 ss 命令来获取网络接口的统计信息&#xff0c;或者通过 top 命令来查看系统中正在运行的进程。 然而&#xff0c;如果你真正…...

大语言模型训练过程中,怎么实现算力共享,采用什么分片规则和共享策略

目录 大语言模型训练过程中,怎么实现算力共享,采用什么分片规则和共享策略 一、算力共享的实现 二、分片规则与共享策略 三、总结 DeepSpeed、Megatron-LM是什么 DeepSpeed ZeRO技术一般不实现调参的 ZeRO技术的实现方式 ZeRO与调参的关系 NCCL是什么 一、NCCL概…...

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现TTAO-Transformer-LSTM多变量回归预测&#xff0c;三角拓扑聚合…...

斐波那契数列(Fibonacci)数列 c++详解

Fibonacci数列是一个在数学和计算机科学中非常著名的数列。这个数列以其特殊的递推关系而闻名&#xff0c;也因其在自然界中的多次出现而引人注目。 定义&#xff1a; Fibonacci数列的定义如下&#xff1a; F(0) 0F(1) 1对于 n > 1&#xff0c;F(n) F(n-1) F(n-2) 也就…...

第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024,9月13-15)

第三届人工智能、物联网与云计算技术国际会议(AIoTC 2024)将于2024年9月13日-15日在中国武汉举行。 本次会议由华中师范大学伍伦贡联合研究院与南京大学联合主办、江苏省大数据区块链与智能信息专委会承办、江苏省概率统计学会、江苏省应用统计学会、Sir Forum、南京理工大学、…...

家具购物小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;家具分类管理&#xff0c;家具新品管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;家具新品&#xff0c;家具公告&#xff0…...

测试面试宝典(三十四)—— token是做什么用的?

Token 在软件系统中通常具有多种重要用途。 首先&#xff0c;它用于身份验证和授权。用户登录成功后&#xff0c;系统会生成一个唯一的 token 并返回给客户端&#xff0c;客户端后续的请求携带这个 token 来证明其身份和访问权限&#xff0c;避免了每次请求都需要重新输入用户…...

计算机网络基础:4.HTTP与HTTPS

一、回顾设定 想象你在经营一家繁忙的餐厅&#xff0c;顾客们通过点餐系统&#xff08;网卡&#xff09;下单&#xff0c;订单被前台&#xff08;路由器&#xff09;接收并分发到各个厨房区域&#xff08;网络设备&#xff09;。光猫像是食材供应商&#xff0c;通过高效的物流系…...

【深度学习入门】安装conda/miniconda、所需包类、CUDA与conda/Miniconda间的关系

深度学习入门 须知 本教程跟随李沐老师课程随笔&#xff0c;课程链接点击此处。 CUDA和Anaconda的关系 CUDA Toolkit是由Nvidia官方提供的完整工具包&#xff0c;其中提供了Nvidia驱动程序、开发CUDA程序相关的开发工具包等。 Anaconda在安装Pytorch等会用到的CUDA的框架时…...

0725,进程间传递文件描述符,socketpair + sendmsg/recvmsg

我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎…...

放大电路总结

补充: 只有直流移动时才有Rbe动态等效电阻 从RsUs看进去,实际上不管接了什么东西都能够看成是一个Ri(输入电阻) Ri Ui/Ii Rb//Rbe Ui/Us Ri/(RiRs) Aus (Uo/Ui)*(Ui/Us) Au *Ri/(RiRs) 当前面是一个电压源的信号 我们就需要输入电阻更大 Ro--->输出电阻--->将…...

深度学习1-简介

人工智能&#xff08;AI&#xff09;旨在打造模仿智能行为的系统。它覆盖了众多方法&#xff0c;涵盖了基于逻辑、搜索和概率推理的技术。机器学习是 AI 的一个分支&#xff0c;它通过对观测数据进行数学模型拟合来学习决策制定。这个领域近年来迅猛发展&#xff0c;现在几乎&a…...

Java基础语法 (基础介绍 二)

目录 Java 基础语法 第一个Java程序 基本语法 Java标识符 Java修饰符 Java变量 Java关键字 Java注释 Java 空行 Java 对象和类 Java中的对象 Java中的类 构造方法 创建对象 访问实例变量和方法 实例 源文件声明规则 Java包 Import语句 一个简单的例子 Java…...

SAPUI5基础知识18 - 自定义CSS和主题色

1. 背景 在上一篇博客中&#xff0c;我们通过使用SAPUI5提供的CSS类实现元素间距的调整。在本篇博客中&#xff0c;让我们看一下如何实现自定义的CSS样式。 2. 背景知识 2.1 CSS基础语法 CSS&#xff0c;全称为级联样式表&#xff08;Cascading Style Sheets&#xff09;&a…...

Postman中API测试的艺术:测试用例复用的高级技巧

Postman中API测试的艺术&#xff1a;测试用例复用的高级技巧 在API测试过程中&#xff0c;复用测试用例可以显著提高测试效率和一致性。Postman作为一个强大的API开发工具&#xff0c;提供了多种机制来实现测试用例的复用。本文将深入探讨Postman中API测试用例复用的技巧&…...

Flutter Geocoding插件使用指南:简化地理编码与逆地理编码

Flutter Geocoding插件使用指南&#xff1a;简化地理编码与逆地理编码 简介 geocoding 是一个Flutter插件&#xff0c;提供了简便的地理编码&#xff08;将地址转换为经纬度坐标&#xff09;和逆地理编码&#xff08;将经纬度坐标转换为地址&#xff09;功能。它利用了iOS和A…...

“手撕”全网最细的JDBC教程(安装导入使用)

目录 一、什么是JDBC 二、JDBC的安装 三、JDBC如何导入 四、怎么使用JDBC编写代码 一、什么是JDBC JDBC由Java提供给数据库的一组通用的API。 在平常的业务中&#xff0c;是比较少使用像cmd命令行来操作数据库的&#xff0c;更多的是操作代码&#xff08;Python&#xff…...

C++指针选择题带答案

1、有如下语句int a10,b20,*p1,*p2;p1&a;p2&b;如图1所示&#xff0c;若要实现图2所示的存储 结构&#xff0c;可选用的赋值语句是___________。 A)*p1*p2; B)p1p2; C&#xff09;p1*p2; D)*p1p2; 2、变量的指针&#xff0c;其含义是该…...

力扣 二分查找

二分查找基础篇。 题目 class Solution {public int searchInsert(int[] nums, int target) {int l 0, r nums.length - 1;while(l < r) {int mid l((r-l)>>1);//(lr)/2if(nums[mid]<target)lmid1;else rmid-1;}return l;//处理边界&#xff0c;设定数组的左半…...

ADMAS-Simulink联合仿真输入设置

使用Solidworks、ADAMS、Simulink进行机电联合仿真_adams-simulink-CSDN博客RecurDynSimulink联合仿真案例演示_哔哩哔哩_bilibili# C#调用已经使用Python训练好的神经网络做图片检测_c#调用python训练好的神经网络模型-CSDN博客...

【NOI】C++程序设计入门三

文章目录 前言一、大杂烩1.导入2.常量3.标识符4.关键字5.整型补充5.1 short&#xff1a;短整型5.2 long&#xff1a;长整型5.3 long long&#xff1a;长长整型 二、例题讲解问题&#xff1a;1597. 买文具问题&#xff1a;1596. 火柴棒三角形问题问题&#xff1a;1417. 买文具问…...

Three.js投射光线实现三维物体交互

<template><div id"webgl"></div> </template><script setup> import * as THREE from three //导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入 dat.gui import { GUI } from thre…...

SSRF学习笔记

1.NAT学习 Nat&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是 一种网络通信技术主要用于将私有网络中的内部IP地址转换成公共网络中的公共IP地址&#xff0c;以实现局域网内部设备访问互联网的功能。具体来说&#xff0c;Nat有以下几个主要…...

Python——Pandas(第三讲)

文章目录 修改替换变量值对应数值的替换指定数值范围的替换 虚拟变量变换数值变量分段数据分组基于拆分进行筛选 分组汇总使用 agg 函数进行汇总引用自定义函数 长宽格式转换转换为最简格式长宽型格式的自由互转 多个数据源的合并数据的横向合并concat 命令 处理缺失值认识缺失…...

性能测试中qps 一直上不去的原因

QPS&#xff1a;Queries Per Second意思是“每秒查询率”&#xff0c;是一台服务器每秒能够相应的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 在性能测试中&#xff0c;QPS&#xff08;每秒查询率&#xff09;一直上不去可能由以下…...

学习笔记14:CNAME 记录值、TTL (Time to Live)、Redis 的 Pool 对象池、钩子函数、依赖注入

CNAME 记录值 CNAME 记录是一种DNS记录类型&#xff0c;它将一个域名映射到另一个域名。这通常用于将一个子域名指向另一个域名&#xff0c;或者将一个域名指向一个不同的顶级域。 用途&#xff1a;用于域名别名&#xff0c;负载均衡&#xff0c;或者在更换域名时保持服务的连…...

springboot集成mybatis时,dao层的mapper类需要添加@Repository注解吗?

在Spring Boot项目中&#xff0c;当你使用MyBatis作为ORM框架时&#xff0c;关于DAO层的Mapper类是否需要添加Repository注解&#xff0c;这主要取决于你的项目需求和配置。 Repository注解的作用Repository注解是Spring框架中用于声明持久层&#xff08;DAO层&#xff09;的组…...

一文总结代理:代理模式、代理服务器

概述 代理在计算机编程领域&#xff0c;是一个很通用的概念&#xff0c;包括&#xff1a;代理设计模式&#xff0c;代理服务器等。 代理类持有具体实现类的实例&#xff0c;将在代理类上的操作转化为实例上方法的调用。为某个对象提供一个代理&#xff0c;以控制对这个对象的…...

探索 Kubernetes 持久化存储之 Longhorn 初窥门径

作者&#xff1a;运维有术星主 在 Kubernetes 生态系统中&#xff0c;持久化存储扮演着至关重要的角色&#xff0c;它是支撑业务应用稳定运行的基石。对于那些选择自建 Kubernetes 集群的运维架构师而言&#xff0c;选择合适的后端持久化存储解决方案是一项至关重要的选型决策。…...

全国区块链职业技能大赛样题第9套智能合约+数据库表设计

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 nice.sql /* Navicat MySQ…...

常见OVS网桥及其链接接口详解

目录 引言OVS简介常见OVS网桥 QBR&#xff08;qbr&#xff09;PLY网桥br-intbr-tunbr-routerbrcps常见网桥链接接口 QVOQVIQVMPatch网桥和接口的工作原理应用场景 虚拟化环境数据中心网络云计算平台 1. 引言 开放虚拟交换机&#xff08;Open vSwitch&#xff0c;简称OVS&…...

创建最最最纯净 Windows 11/10 系统镜像!| 全网独一份

前期准备工作 1.配置系统应答文件&#xff1a;【点击前往】 2.系统镜像编辑器&#xff1a; 【点击下载】 3.Windows 系统镜像官方下载&#xff1a; 【Windows 11】、【Windows 10】【官方密钥】 4.翻译工具 【GitHub】 5.详细的设置教程 5.1先打开配置系统应答文件&#…...

带你学会Git必会操作

文章目录 带你学会Git必会操作1Git的安装2.Git基本操作2.1本地仓库的创建2.2配置本地仓库 3.认识一些Git的基本概念3.1操作流程&#xff1a; 4.一些使用场景4.1添加文件场景一4.2查看git文件4.3修改文件4.4Git版本回退4.5git撤销修改 5.分支管理5.1查看分支5.2创建本地分支5.3切…...

clickhouse处理readonly报错

1&#xff0c;clickhouse执行 SYSTEM RESTORE REPLICA db_com.dwd_com_t_judge_result_local; SYSTEM RESTORE REPLICA db_com.dwd_com_t_judge_result_local Query id: 70669be0-eef8-41da-b761-4980ce48ece2 0 rows in set. Elapsed: 0.001 sec. Received exception fro…...

使用git命令行的方式,将本地项目上传到远程仓库

在国内的开发环境中&#xff0c;git的使用是必不可少的。Git 是一款分布式版本控制系统&#xff0c;用于有效管理和追踪文件的变更历史及协作开发。本片文章就来介绍一下怎样使用git命令行的方式&#xff0c;将本地项目上传到远程仓库&#xff0c;虽然现在的IDE中基本都配置了g…...

jetbrains InterlliJ IDEA 2024.1 版本最新特性一览: Java 相关内容

简简单单 Online zuozuo:欢迎商业合作 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo :联系我们:VX :tja6288 / EMAIL: 347969164@qq.com 文章目录 jetbrains InterlliJ …...

百日筑基第三十四天-JAVA中的强/软/弱/虚引用

百日筑基第三十四天-JAVA中的强/软/弱/虚引用 Java对象的引用被划分为4种级别&#xff0c;分别为强引用、软引用、弱引用以及虚引用。帮助程序更加灵活地控制对象的生命周期和JVM进行垃圾回收。 强引用 强引用是最普遍的引用&#xff0c;一般把一个对象赋给一个引用变量&…...