使用ROCm的GPU感知MPI

GPU-aware MPI with ROCm — ROCm Blogs (amd.com)

注意: 此博客之前是 AMD Lab Notes博客系列的一部分。

MPI(消息传递接口)是高性能计算中进程间通信的事实标准。MPI进程在其本地数据上进行计算,同时进行大量的相互通信。这使得MPI程序可以在具有分布式内存空间的系统(例如集群)上执行。MPI支持不同类型的通信,包括点对点通信和集体通信。

点对点通信是基本的通信机制,其中发送进程和接收进程都参与通信。发送方有一个包含消息的缓冲区和一个包含接收方将使用的信息(例如,消息标签、发送方的排名编号等)的信封。接收方使用信封中的信息选择指定的消息并将其存储在接收缓冲区中。

在集体通信中,消息可以在一组进程之间交换,而不仅仅是两个进程之间。集体通信提供了一种方便、可移植和优化的方式,使进程能进行一对多和多对多的通信。一些集体通信的例子包括广播(broadcast)、全部收集(allgather)、全部到全部(alltoall)和全部归约(allreduce)。

GPU感知的MPI

如今,许多MPI应用程序支持在GPU集群上执行。在这些应用程序中,计算密集型部分代码被卸载并加速到GPU上执行,也被称为设备。当涉及到MPI通信时,MPI进程需要通信驻留在GPU缓冲区中的数据。GPU感知的MPI提供了一种将GPU缓冲区传递给MPI调用的机会。这减轻了程序员通过主机内存加载GPU缓冲区的负担,使他们能够开发出更具可读性和简洁性的应用程序。此外,它还可以利用ROCm RDMA(远程直接内存访问)等加速技术使应用程序运行得更加高效。ROCm RDMA使得第三方设备(如Mellanox Infiniband HCA,主机通道适配器)可以与GPU内存直接进行点对点数据路径传输,而无需主机干预。大多知名的MPI实现,包括OpenMPI、MVAPICH2和Cray MPICH都支持GPU感知通信。

下面的代码展示了一个简单的GPU感知的点对点通信示例:

#include <stdio.h>
#include <hip/hip_runtime.h>
#include <mpi.h>int main(int argc, char **argv) {int i,rank,size,bufsize;int *h_buf;int *d_buf;MPI_Status status;bufsize=100;MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &size);//allocate buffersh_buf=(int*) malloc(sizeof(int)*bufsize);hipMalloc(&d_buf, bufsize*sizeof(int));//initialize buffersif(rank==0) {for(i=0;i<bufsize;i++)h_buf[i]=i;}if(rank==1) {for(i=0;i<bufsize;i++)h_buf[i]=-1;}hipMemcpy(d_buf, h_buf, bufsize*sizeof(int), hipMemcpyHostToDevice);//communicationif(rank==0)MPI_Send(d_buf, bufsize, MPI_INT, 1, 123, MPI_COMM_WORLD);if(rank==1)MPI_Recv(d_buf, bufsize, MPI_INT, 0, 123, MPI_COMM_WORLD, &status);//validate resultsif(rank==1) {hipMemcpy(h_buf, d_buf, bufsize*sizeof(int), hipMemcpyDeviceToHost);for(i=0;i<bufsize;i++) {if(h_buf[i] != i)printf("Error: buffer[%d]=%d but expected %d\n", i, h_buf[i], i);}fflush(stdout);}//free buffersfree(h_buf);hipFree(d_buf);MPI_Finalize();
}

如代码所示,我们将GPU缓冲区(`d_buf`)传递给`MPI_Send`和`MPI_Recv`调用。这个缓冲区是用hipMalloc在GPU上分配的。
要编译和运行此代码,您需要在系统上有ROCm以及GPU感知的MPI实现。您可以在[AMD ROCm™安装](AMD ROCm™ installation — ROCm Blogs)中找到ROCm安装说明。不同MPI实现下构建和运行上述代码(gpu-aware.cpp)的说明将在本文档后面讨论。

使用 OpenMPI 进行 GPU 感知通信

如前所述,大多数知名的 MPI 实现都支持 GPU 感知通信。在本节中,我们提供了使用 ROCm 支持构建 GPU 感知 OpenMPI 的说明。

要构建具有 ROCm 支持的 GPU 感知 OpenMPI,首先需要安装 Unified Communication X ([UCX](Home - UCX-Unified Communication X UCX-Unified Communication X))。UCX 是一种用于高带宽和低延迟网络的通信框架。请使用以下命令来构建 UCX(版本 1.14):

git clone https://github.com/openucx/ucx.git
cd ucx
git checkout v1.14.x
./autogen.sh
./configure --prefix=$HOME/.local --with-rocm=/opt/rocm --without-knem --without-cuda --enable-gtest --enable-examples
make -j
make install

成功安装后,UCX 将会在 $HOME/.local 目录中可用。现在,我们可以使用以下命令安装具有 ROCm 支持的 GPU 感知 OpenMPI:

git clone --recursive -b v5.0.x git@github.com:open-mpi/ompi.git
cd ompi/
./autogen.pl
./configure --prefix=$HOME/.local --with-ucx=$HOME/.local
make -j
make install

从 OpenMPI 5.0 开始,我们还可以在配置命令中添加 --with-rocm=/opt/rocm,以利用 Open MPI 中的一些 ROCm 功能,例如派生数据类型、MPI I/O 等。成功安装后,具有 ROCm 支持的 OpenMPI 将可在 $HOME/.local 中找到。接下来,我们可以按以下方式设置 PATH 和 LD_LIBRARY_PATH:

export PATH=$HOME/.local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH

要使用 OpenMPI 编译一个 GPU 感知的 MPI 程序(如 gpu-aware.cpp),需要将 OMPI_CC 环境变量设置为 hipcc,以更改 mpicc 包装器的编译器。然后可以使用 mpicc 编译代码并使用 mpirun 运行代码:

export OMPI_CC=hipcc
mpicc -o ./gpu-aware ./gpu-aware.cpp
mpirun -n 2 ./gpu-aware

GPU感知通信与Cray MPICH

在本节中,我们讨论如何使用Cray MPICH构建和运行GPU感知的MPI程序。首先,确保您的系统上已加载ROCm、Cray MPICH和`craype-accel-amd-gfx90a/craype-accel-amd-gfx908`模块。您有两种编译代码的选择:

选项1:使用Cray编译器包装器编译代码并链接ROCm:

cc -o ./gpu-aware ./gpu-aware.cpp -I/opt/rocm/include/ -L/opt/rocm/lib  -lamdhip64 -lhsa-runtime64

选项2:使用hipcc编译代码并链接Cray MPICH:

hipcc -o ./gpu-aware ./gpu-aware.cpp -I/opt/cray/pe/mpich/8.1.18/ofi/cray/10.0/include/ -L/opt/cray/pe/mpich/8.1.18/ofi/cray/10.0/lib -lmpi

成功编译后,可以使用以下命令运行代码:

export MPICH_GPU_SUPPORT_ENABLED=1
srun -n 2 ./gpu-aware

请注意,将`MPICH_GPU_SUPPORT_ENABLED`设置为1,以启用GPU感知的通信。

使用OSU微基准测试进行性能测量

OSU微基准测试(OMB)提供了一系列MPI基准测试,用于测量各种MPI操作的性能,包括点对点、集合、基于主机和基于设备的通信。在本节中,我们讨论如何使用OSU微基准测试测量设备到设备的通信带宽。我们使用前面讨论的OpenMPI安装进行本节的实验。

您可以使用以下命令来构建支持ROCm的OSU微基准测试:

wget https://mvapich.cse.ohio-state.edu/download/mvapich/osu-micro-benchmarks-7.0.1.tar.gz
tar -xvf osu-micro-benchmarks-7.0.1.tar.gz
cd osu-micro-benchmarks-7.0.1
./configure --prefix=$HOME/.local/ CC=$HOME/.local/bin/mpicc CXX=$HOME/.local/bin/mpicxx --enable-rocm --with-rocm=/opt/rocm
make -j
make install

安装成功后,OSU微基准测试将位于`$HOME/.local/`。您可以使用以下命令运行带宽测试:

mpirun -n 2 $HOME/.local/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw  D D

在带宽测试中,发送进程将固定数量的消息背靠背发送给接收进程。接收进程在接收到所有这些消息后会发送一个回复。这个过程会重复多次。带宽是根据经过的时间和传输的字节数计算的。上述命令末尾的`D D`指定我们希望发送和接收缓冲区分配在设备上。

如果您没有获得预期的带宽,可能是OpenMPI默认没有使用UCX。要强制OpenMPI使用UCX,可以在mpirun命令中添加以下参数:

mpirun --mca pml ucx --mca pml_ucx_tls ib,sm,tcp,self,cuda,rocm -np 2 $HOME/.local/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw D D

您还可以使用以下命令运行集合通信测试:

mpirun -n 4 $HOME/.local/libexec/osu-micro-benchmarks/mpi/collective/osu_allreduce -d rocm

上述命令使用四个进程运行MPI_Allreduce延迟测试。在此测试中,基准测试会测量在大量迭代中,不同消息长度下四个进程间MPI_Allreduce集合操作的平均延迟。
-d rocm指定进程应将通信缓冲区分配在GPU设备上。

GPU-to-GPU 通信选项

在本节中,我们讨论了在使用 [AMD Instinct™ MI250](AMD Instinct™ MI250 Accelerators) 和 [AMD Instinct™ MI250X](https://www.amd.com/en/products/server-accelerators/instinct-mi250x) GPU 的系统中,GPU 对 GPU 的通信选项。每个 MI250(X) GPU 由两个图形计算芯片(GCD)组成。下图显示了一个包含 4 个 MI250 GPU(8 个 GCD)的节点的图表。每个绿色框表示一个具有两个 GCD 的 MI250 GPU。GCD 通过 Infinity Fabric 链接连接。每个 Infinity Fabric 链接的峰值带宽达到 50 GB/s。正如图中所示,不同的 GCD 之间存在不同数量的 Infinity Fabric 链接。例如,同一个 GPU 上的 GCD 通过 4 个链接连接,而不同 GPU 上的 GCD 通过 1 个或 2 个链接连接。从图中还能看出,不同的 GCD 之间有不同数量的跳数。例如,GCD 1 通过一次跳跃连接到 GCD 3,而 GCD 0 至少通过两次跳跃连接到 GCD 3。GCD 之间的最大可实现带宽取决于 GCD 之间的 Infinity Fabric 链接数量和跳数。

图 1:包含 4 个 MI250 GPU(8 个 GCD)的节点的图表。每个绿色框是一个具有两个 GCD 的 MI250 GPU。GCD 通过 Infinity Fabric 链接连接。

GPU 对 GPU 的通信有两个选项:
1. 使用系统直接内存访问 (SDMA) 引擎
2. 启动一个内核来处理通信

SDMA 引擎提供了与计算重叠进行通信的机会。然而,其缺点是它在 GCD 之间提供最大带宽为 50 GB/s。相比之下,内核提供了更高的通信带宽,但它们需要 CU 来移动数据,因此使用内核时与计算重叠通信的机会较少。可以使用环境变量 HSA_ENABLE_SDMA 来选择使用 SDMA 引擎还是内核。在 ROCM 5.4 及以下版本中,默认使用 SDMA 引擎。

以下实验 [1]展示了 GCD 0 与其对等设备间的通信带宽,对于大小为 16MB 的消息。我们将 HSA_ENABLE_SDMA 设置为 0,因此会启动一个内核来处理通信。我们设置 HIP_VISIBLE_DEVICES 来为每个实验选择对等的 GCD。使用 “-m ((16*1024*1024)):((16*1024*1024))” 我们指定我们感兴趣的消息大小,在此示例中为 16MiB。

export HSA_ENABLE_SDMA=0
export HIP_VISIBLE_DEVICES=0,1
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216           142235.39export HIP_VISIBLE_DEVICES=0,2
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            38963.65export HIP_VISIBLE_DEVICES=0,3
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            36903.57export HIP_VISIBLE_DEVICES=0,4
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            36908.74export HIP_VISIBLE_DEVICES=0,5
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            34986.54export HIP_VISIBLE_DEVICES=0,6
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            76276.14export HIP_VISIBLE_DEVICES=0,7
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            68788.80

上述实验表明,不同的 GCD 对之间存在不同的通信带宽。如前所述,这取决于 GCD 之间的 Infinity Fabric 链路数量以及跳数。例如,GCD 0 和 1 之间的通信带宽约为 142 GB/s,它们通过四条 Infinity Fabric 链接相连。每条 Infinity Fabric 链接的理论峰值带宽为 50 GB/s,因此 GCD 0 和 1 之间的理论峰值带宽为 200 GB/s。假设可实现的带宽约为理论带宽的 70%,那么预期 GCD 0 和 1 之间的通信带宽约为 142 GB/s。对于 GCD 0 和 2,它们通过一条 Infinity Fabric 链接相连,带宽为 38 GB/s。GCD 0 和 3 通过两跳相连,所以实现的带宽略低(约为 36 GB/s)。我们可以使用相同的逻辑来推理其他 GCD 对之间的通信带宽。

使用 SDMA 引擎时,我们得到的最大带宽约为 50 GB/s,正如前面讨论的那样:

export HSA_ENABLE_SDMA=1
export HIP_VISIBLE_DEVICES=0,1
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            49396.52export HIP_VISIBLE_DEVICES=0,2
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            41925.10export HIP_VISIBLE_DEVICES=0,3
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            41019.50export HIP_VISIBLE_DEVICES=0,4
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            42243.36export HIP_VISIBLE_DEVICES=0,5
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            41870.39export HIP_VISIBLE_DEVICES=0,6
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            49386.80export HIP_VISIBLE_DEVICES=0,7
mpirun -n 2 $OMB_DIR/libexec/osu-micro-benchmarks/mpi/pt2pt/osu_bw -m $((16*1024*1024)):$((16*1024*1024)) D D
# OSU MPI-ROCM Bandwidth Test v7.0
# Send Buffer on DEVICE (D) and Receive Buffer on DEVICE (D)
# Size      Bandwidth (MB/s)
16777216            49369.06

[附代码示例]

作者要感谢 Edgar Gabriel 和 Maria Ruiz Varela 对本文的有益评论和反馈。如果您有任何问题或意见,请在 GitHub 上联系我们 [讨论区](https://github.com/ROCm/rocm-blogs/discussions)

[1] 测试使用 ROCm 5.4、UCX 1.14 和 OpenMPI 5.0 进行。本文件中的测试结果不代表官方性能数据,但反映了不同通信选项的影响。实际性能取决于系统配置和环境设置。

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

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

相关文章

【折半查找】

目录 一. 折半查找的概念二. 折半查找的过程三. 折半查找的代码实现四. 折半查找的性能分析 \quad 一. 折半查找的概念 \quad 必须有序 \quad 二. 折半查找的过程 \quad \quad 三. 折半查找的代码实现 \quad 背下来 \quad 四. 折半查找的性能分析 \quad 记住 比较的是层数 …

sed引入变量中的坑

sed引入变量问题 1、sed引入变量2、sed引入变量问题 1、sed引入变量 sed指令引入变量&#xff0c;直接使用双引号即可 例如&#xff0c;下面的示例&#xff1a; ab; echo "abc" | sed "s/b/$a/g"2、sed引入变量问题 但是&#xff0c;如果变量值中带有/等…

自闭症寄宿学校:释放孩子内心的美

在自闭症儿童的成长旅程中&#xff0c;寻找一个既能提供专业康复服务&#xff0c;又能让孩子感受到爱与关怀的教育环境&#xff0c;是许多家庭梦寐以求的目标。在广州&#xff0c;星贝育园自闭症儿童寄宿制学校正是这样一所充满爱与希望的学校&#xff0c;它不仅为自闭症儿童提…

CMU 10423 Generative AI:lec13/13.5(text-to-image models:三大类方法、评估标准、图像编辑原理)

1 文章目录 1 lec13和lec13.5概述2 Text-to-Image Generation 概念、主要方法、挑战、发展历程1. **基本概念**2. **主要技术方法**2.1. **生成对抗网络&#xff08;GAN&#xff09;**2.2. **自回归模型&#xff08;Autoregressive Models&#xff09;**2.3. **扩散模型&#x…

9.28学习笔记

1.ping 网址 2.ssh nscc/l20 3.crtl,打开vscode的setting 4.win 10修改ssh配置文件及其密钥权限为600 - 晴云孤魂 - 博客园 整体来看&#xff1a; 使用transformer作为其主干网络&#xff0c;代替了原先的UNet 在latent space进行训练&#xff0c;通过transformer处理潜…

Java项目实战II基于Java+Spring Boot+MySQL的智能物流管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着电商行业的蓬勃发展&#xff0c;物流行业迎来了前所未有的机遇与挑战。面对日益增长的订单量和复…

python如何显示数组

np.set_printoptions方法的相关属性&#xff1a; <span style"background-color:#272822"><span style"color:#f8f8d4">set_printoptions(precisionNone, thresholdNone, edgeitemsNone, linewidthNone, suppressNone, nanstrNone, infstrNo…

记一次RCE漏洞的利用

某微商代理商补货商城系统存在RCE漏洞 微商分销代理商城&#xff0c;可以自己设置代理等级和升级条件(如购买指定商品、消费额度)&#xff0c;“微商城小程序三级分销拼团秒杀多商户开店O2O门店”通过社交关系分销裂变&#xff0c;把粉丝变成客户&#xff0c;让分销商发展下线…

MDM监管锁系统ABM证书与MDM证书申请与使用

MDM证书与ABM证书申请与维护 基础知识 监管锁系统运行需要两个证书 分别为ABM证书 与 MDM证书,在别人平台购买的监管锁只会让你上传自己的ABM证书而MDM证书则是共用一个平台自己的MDM证书&#xff0c;而MDM证书才是控制手机的关键,如果MDM证书被封禁,那么所有的设备将无法受到…

MDM监管锁系统上锁流程

上锁与解锁 上锁设备 完整的上锁流程可参考: https://b23.tv/UvM35sU 上锁需要已经注册了一个普通用户 并使用管理员分配了台数 且有可用的MDM证书和ABM证书(公有和私有的都可以 只要有可用的就可以) 一部用来上锁的手机 链接wifi wifi必须要是2.4g频段 不要使用5gwifi 上锁…

PYTHON实现HTTP request的一些有用的函数

前言 我们知道&#xff0c;当需要设计一个程序和服务器进行交互时&#xff0c;往往会用到HTTP的request&#xff0c;即服务器有一个对外接口REST API&#xff0c;因此当向服务器发送符合格式要求的HTTP request时&#xff0c;服务器会给出响应&#xff0c;甚至执行一些任务。如…

睢宁自闭症寄宿学校:培养特殊孩子的未来

在自闭症儿童的教育与康复领域&#xff0c;每一所学校的努力都是对孩子们未来无限可能的一次深刻诠释。从江苏睢宁到广东广州&#xff0c;自闭症寄宿学校正以不同的方式&#xff0c;为这些特殊的孩子铺设一条通往未来的希望之路。其中&#xff0c;广州的星贝育园自闭症儿童寄宿…

【算法篇】回溯算法类(1)(笔记)

目录 一、理论基础 1. 相关题目 2. 遍历过程 3. 代码框架 二、LeetCode 题目 1. 组合 2. 组合总和III 3. 电话号码的字母组合 4. 组合总和 5. 组合总和II 6. 分割回文串 7. 复原IP地址 8. 子集 一、理论基础 1. 相关题目 2. 遍历过程 3. 代码框架 void backtr…

SSM环卫人员管理平台—计算机毕业设计源码36412

目 录 摘要 1 绪论 1.1背景及意义 1.2国内外研究概况 1.3研究内容 1.4 ssm框架介绍 1.5论文结构与章节安排 2 环卫人员管理平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.2.2数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1 功能性…

JAVAIDEA初始工程的创建

四结构 建工程综述* 初始*&#xff1a; 1、先建个空项目&#xff0c; 2、打开文件中的项目结构新建module模块&#xff08;模块下有src&#xff09; 修改模块名&#xff1a; 也是Refactor&#xff0c;Rename&#xff0c;但是要选第三个同时改模块和文件夹名字 导入模块&am…

C++——模拟实现vector

1.查看vector的源代码 2.模拟实现迭代器 #pragma oncenamespace jxy {//模板尽量不要分离编译template <class T>class vector{public:typedef T* iterator;//typedef会受到访问限定符的限制typedef const T* const_iterator;//const迭代器是指向的对象不能修改&#xf…

开发和软件工程一样吗?

时间&#xff1a;2024年 10月 02日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频&#xff1a;喜马拉雅 大家好&#xff0c;欢迎来到“小蒋聊技术”&#xff0c;我是小蒋&#xff01; 今天咱们要聊的话题是——开发和软件工…

17.反射与动态代理

目录 1.反射的概述 2.学习反射到底学什么&#xff1f; 3.字节码文件和字节码文件对象 4.获取字节码文件对象的三种方式 5.Class类中用于获取构造方法的方法 6.Class类中用于获取成员变量的方法 7.Class类中用于获取成员方法的方法 8.反射和配置文件结合动态获取的练习与利用反…

Java类和对象、自定义包、static、代码块、方法重写

目录 1.类和对象 2.this指针 3.对象的构造和初始化 3.1默认初始化 3.2就地初始化 3.3构造初始化 3.4IDEA快速填充 3.5使用this简化 3.6初始化的总结 4.包的引入 4.1包的概念 4.2导入包中的类 4.3自定义包 5.static修饰 6.代码块的划分 7.方法重写 1.类和对象 使…

C++系列-多态

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 多态 多态就是不同类型的对象&#xff0c;去做同一个行为&#xff0c;但是产生的结果是不同的。 比如说&#xff1a; 都是动物叫声&#xff0c;猫是喵喵&#xff0c;狗是汪汪&am…