1. CUDA中的grid和block

1. CUDA中的grid和block基本的理解

在这里插入图片描述

  1. Kernel: Kernel不是CPU,而是在GPU上运行的特殊函数。你可以把Kernel想象成GPU上并行执行的任务。当你从主机(CPU)调用Kernel时,它在GPU上启动,并在许多线程上并行运行。

  2. Grid: 当你启动Kernel时,你会定义一个网格(grid)。网格是一维、二维或三维的,代表了block的集合。

  3. Block: 每个block内部包含了许多线程。block也可以是一维、二维或三维的。

  4. Thread: 每个线程是Kernel的单个执行实例。在一个block中的所有线程可以共享一些资源,并能够相互通信。

你正确地指出,grid、block和thread这些概念在硬件级别上并没有直接对应的实体,它们是抽象的概念,用于组织和管理GPU上的并行执行。然而,GPU硬件是专门设计来支持这种并行计算模型的,所以虽然线程在物理硬件上可能不是独立存在的,但是它们通过硬件架构和调度机制得到了有效的支持。

另外,对于线程的管理和调度,GPU硬件有特定的线程调度单元,如NVIDIA的warp概念。线程被组织成更小的集合,称为warps(在NVIDIA硬件上),并且这些warps被调度到硬件上以供执行。

所以,虽然这些概念是逻辑和抽象的,但它们与硬件的实际执行密切相关,并由硬件特性和架构直接支持。

一般来说:

• 一个kernel对应一个grid

• 一个grid可以有多个block,一维~三维

• 一个block可以有多个thread,一维~三维

2. 1D traverse

在这里插入图片描述

void print_one_dim(){int inputSize = 8;int blockDim = 4;int gridDim = inputSize / blockDim; // 2// 定义block和grid的维度dim3 block(blockDim);  // 说明一个block有多少个threadsdim3 grid(gridDim);    // 说明一个grid里面有多少个block /* 这里建议大家吧每一函数都试一遍*/print_idx_kernel<<<grid, block>>>();// print_dim_kernel<<<grid, block>>>();// print_thread_idx_per_block_kernel<<<grid, block>>>();// print_thread_idx_per_grid_kernel<<<grid, block>>>();cudaDeviceSynchronize();
}

我觉得重点在这两行

  1. dim3 block(blockDim);: 这一行创建了一个三维向量block,用来定义每个block的大小。在这个例子中,blockDim是一个整数值4,所以每个block包含4个线程。dim3数据类型是CUDA中的一个特殊数据类型,用于表示三维向量。在这个情况下,你传递了一个整数值,所以block的其余维度将被默认设置为1。这意味着你将有一个包含4个线程的一维block。

  2. dim3 grid(gridDim);: 这一行创建了一个三维向量grid,用来定义grid的大小。gridDim的计算基于输入大小(inputSize)和每个block的大小(blockDim)。在这个例子中,inputSize是8,blockDim是4,所以gridDim会是2。这意味着整个grid将包含2个block。与block一样,你传递了一个整数值给grid,所以其余维度将被默认设置为1,得到一个一维grid。

总体来说,这两行代码定义了内核的执行配置,将整个计算空间划分为2个block,每个block包含4个线程。你可以想象这个配置如下:

  • Block 0: 线程0, 线程1, 线程2, 线程3
  • Block 1: 线程4, 线程5, 线程6, 线程7

然后,当你调用内核时,这些线程将被用来执行你的代码。每个线程可以通过其线程索引和block索引来访问自己在整个grid中的唯一位置。这些索引用于确定每个线程应处理的数据部分。

block idx:   1, thread idx in block:   0, thread idx:   4
block idx:   1, thread idx in block:   1, thread idx:   5
block idx:   1, thread idx in block:   2, thread idx:   6
block idx:   1, thread idx in block:   3, thread idx:   7
block idx:   0, thread idx in block:   0, thread idx:   0
block idx:   0, thread idx in block:   1, thread idx:   1
block idx:   0, thread idx in block:   2, thread idx:   2
block idx:   0, thread idx in block:   3, thread idx:   3

3. 2D打印

// 8个线程被分成了两个
void print_two_dim(){int inputWidth = 4;int blockDim = 2;  int gridDim = inputWidth / blockDim;dim3 block(blockDim, blockDim);dim3 grid(gridDim, gridDim);/* 这里建议大家吧每一函数都试一遍*/// print_idx_kernel<<<grid, block>>>();// print_dim_kernel<<<grid, block>>>();// print_thread_idx_per_block_kernel<<<grid, block>>>();print_thread_idx_per_grid_kernel<<<grid, block>>>();cudaDeviceSynchronize();
}
  1. dim3 block(blockDim, blockDim);: 这里创建了一个二维的block,每个维度的大小都是blockDim,在这个例子中是2。因此,每个block都是2x2的,包含4个线程。由于dim3定义了一个三维向量,没有指定的第三维度会默认为1。

  2. dim3 grid(gridDim, gridDim);: 同样,grid也被定义为二维的,每个维度的大小都是gridDim。由于inputWidth是4,并且blockDim是2,所以gridDim会是2。因此,整个grid是2x2的,包括4个block。第三维度同样默认为1。

因此,整个执行配置定义了2x2的grid,其中包括4个2x2的block,总共16个线程。你可以将整个grid可视化如下:

  • Block (0,0):

    • 线程(0,0), 线程(0,1)
    • 线程(1,0), 线程(1,1)
  • Block (0,1):

    • 线程(2,0), 线程(2,1)
    • 线程(3,0), 线程(3,1)
  • Block (1,0):

    • 线程(4,0), 线程(4,1)
    • 线程(5,0), 线程(5,1)
  • Block (1,1):

    • 线程(6,0), 线程(6,1)
    • 线程(7,0), 线程(7,1)

输出中的“block idx”是整个grid中block的线性索引,而“thread idx in block”是block内线程的线性索引。最后的“thread idx”是整个grid中线程的线性索引。

请注意,执行的顺序仍然是不确定的。你看到的输出顺序可能在不同的运行或不同的硬件上有所不同。

block idx:   3, thread idx in block:   0, thread idx:  12
block idx:   3, thread idx in block:   1, thread idx:  13
block idx:   3, thread idx in block:   2, thread idx:  14
block idx:   3, thread idx in block:   3, thread idx:  15
block idx:   2, thread idx in block:   0, thread idx:   8
block idx:   2, thread idx in block:   1, thread idx:   9
block idx:   2, thread idx in block:   2, thread idx:  10
block idx:   2, thread idx in block:   3, thread idx:  11
block idx:   1, thread idx in block:   0, thread idx:   4
block idx:   1, thread idx in block:   1, thread idx:   5
block idx:   1, thread idx in block:   2, thread idx:   6
block idx:   1, thread idx in block:   3, thread idx:   7
block idx:   0, thread idx in block:   0, thread idx:   0
block idx:   0, thread idx in block:   1, thread idx:   1
block idx:   0, thread idx in block:   2, thread idx:   2
block idx:   0, thread idx in block:   3, thread idx:   3

4. 3D grid

dim3 block(3, 4, 2);
dim3 grid(2, 2, 2);
  1. Block布局 (dim3 block(3, 4, 2)):

    • 这定义了每个block的大小为3x4x2,所以每个block包含24个线程。
    • 你可以将block视为三维数组,其中x方向有3个元素,y方向有4个元素,z方向有2个元素。
  2. Grid布局 (dim3 grid(2, 2, 2)):

    • 这定义了grid的大小为2x2x2,所以整个grid包含8个block。
    • 你可以将grid视为三维数组,其中x方向有2个元素,y方向有2个元素,z方向有2个元素。
    • 由于每个block包括24个线程,所以整个grid将包括192个线程。

整体布局可以视为8个3x4x2的block,排列为2x2x2的grid。

如果我们想用文字来表示整个结构,可能会是这样的:

  • Grid[0][0][0]:
    • Block(3, 4, 2) – 24个线程
  • Grid[0][0][1]:
    • Block(3, 4, 2) – 24个线程
  • Grid[0][1][0]:
    • Block(3, 4, 2) – 24个线程
  • Grid[0][1][1]:
    • Block(3, 4, 2) – 24个线程
  • Grid[1][0][0]:
    • Block(3, 4, 2) – 24个线程
  • Grid[1][0][1]:
    • Block(3, 4, 2) – 24个线程
  • Grid[1][1][0]:
    • Block(3, 4, 2) – 24个线程
  • Grid[1][1][1]:
    • Block(3, 4, 2) – 24个线程

这种三维结构允许在物理空间中进行非常自然的映射,尤其是当你的问题本身就具有三维的特性时。例如,在处理三维物理模拟或体素数据时,这种映射可能非常有用。

5. 通过维度打印出来对应的thread

在这里插入图片描述

比较推荐的打印方式

__global__ void print_cord_kernel(){int index = threadIdx.z * blockDim.x * blockDim.y + \threadIdx.y * blockDim.x + \threadIdx.x;int x  = blockIdx.x * blockDim.x + threadIdx.x;int y  = blockIdx.y * blockDim.y + threadIdx.y;printf("block idx: (%3d, %3d, %3d), thread idx: %3d, cord: (%3d, %3d)\n",blockIdx.z, blockIdx.y, blockIdx.x,index, x, y);
}

index是线程索引的问题,首先,考虑z维度。对于每一层z,都有blockDim.x * blockDim.y个线程。所以threadIdx.z乘以该数量给出了前面层中的线程总数,从图上看也就是越过了多少个方块

然后,考虑y维度。对于每一行y,都有blockDim.x个线程。所以threadIdx.y乘以该数量给出了当前层中前面行的线程数,也就是在当前方块的xy面我们走了几个y, 几行

最后加上thread x完成索引的坐标

void print_cord(){int inputWidth = 4;int blockDim = 2;int gridDim = inputWidth / blockDim;dim3 block(blockDim, blockDim);dim3 grid(gridDim, gridDim);print_cord_kernel<<<grid, block>>>();// print_thread_idx_per_grid_kernel<<<grid, block>>>();cudaDeviceSynchronize();
}
block idx: (  0,   1,   0), thread idx:   0, cord: (  0,   2)
block idx: (  0,   1,   0), thread idx:   1, cord: (  1,   2)
block idx: (  0,   1,   0), thread idx:   2, cord: (  0,   3)
block idx: (  0,   1,   0), thread idx:   3, cord: (  1,   3)
block idx: (  0,   1,   1), thread idx:   0, cord: (  2,   2)
block idx: (  0,   1,   1), thread idx:   1, cord: (  3,   2)
block idx: (  0,   1,   1), thread idx:   2, cord: (  2,   3)
block idx: (  0,   1,   1), thread idx:   3, cord: (  3,   3)
block idx: (  0,   0,   1), thread idx:   0, cord: (  2,   0)
block idx: (  0,   0,   1), thread idx:   1, cord: (  3,   0)
block idx: (  0,   0,   1), thread idx:   2, cord: (  2,   1)
block idx: (  0,   0,   1), thread idx:   3, cord: (  3,   1)
block idx: (  0,   0,   0), thread idx:   0, cord: (  0,   0)
block idx: (  0,   0,   0), thread idx:   1, cord: (  1,   0)
block idx: (  0,   0,   0), thread idx:   2, cord: (  0,   1)
block idx: (  0,   0,   0), thread idx:   3, cord: (  1,   1)

跟之前2D的一样, 同样看起来有点乱,是因为是异步执行的

6. 最后看一个多个grid的案例

void print_coordinates() {dim3 block(3, 4, 2);dim3 grid(2, 2, 2);print_cord_kernel<<<grid, block>>>();cudaDeviceSynchronize(); // 确保内核完成后才继续执行主机代码
}
block idx: (  0,   1,   0), thread idx:   0, cord: (  0,   4)
block idx: (  0,   1,   0), thread idx:   1, cord: (  1,   4)
block idx: (  0,   1,   0), thread idx:   2, cord: (  2,   4)
block idx: (  0,   1,   0), thread idx:   3, cord: (  0,   5)
block idx: (  0,   1,   0), thread idx:   4, cord: (  1,   5)
block idx: (  0,   1,   0), thread idx:   5, cord: (  2,   5)
block idx: (  0,   1,   0), thread idx:   6, cord: (  0,   6)
block idx: (  0,   1,   0), thread idx:   7, cord: (  1,   6)
block idx: (  0,   1,   0), thread idx:   8, cord: (  2,   6)
block idx: (  0,   1,   0), thread idx:   9, cord: (  0,   7)
block idx: (  0,   1,   0), thread idx:  10, cord: (  1,   7)
block idx: (  0,   1,   0), thread idx:  11, cord: (  2,   7)
block idx: (  0,   1,   0), thread idx:  12, cord: (  0,   4)
block idx: (  0,   1,   0), thread idx:  13, cord: (  1,   4)
block idx: (  0,   1,   0), thread idx:  14, cord: (  2,   4)
block idx: (  0,   1,   0), thread idx:  15, cord: (  0,   5)
block idx: (  0,   1,   0), thread idx:  16, cord: (  1,   5)
block idx: (  0,   1,   0), thread idx:  17, cord: (  2,   5)
block idx: (  0,   1,   0), thread idx:  18, cord: (  0,   6)
block idx: (  0,   1,   0), thread idx:  19, cord: (  1,   6)
block idx: (  0,   1,   0), thread idx:  20, cord: (  2,   6)
block idx: (  0,   1,   0), thread idx:  21, cord: (  0,   7)
block idx: (  0,   1,   0), thread idx:  22, cord: (  1,   7)
block idx: (  0,   1,   0), thread idx:  23, cord: (  2,   7)
block idx: (  1,   1,   1), thread idx:   0, cord: (  3,   4)
block idx: (  1,   1,   1), thread idx:   1, cord: (  4,   4)
block idx: (  1,   1,   1), thread idx:   2, cord: (  5,   4)
block idx: (  1,   1,   1), thread idx:   3, cord: (  3,   5)
block idx: (  1,   1,   1), thread idx:   4, cord: (  4,   5)
block idx: (  1,   1,   1), thread idx:   5, cord: (  5,   5)
block idx: (  1,   1,   1), thread idx:   6, cord: (  3,   6)
block idx: (  1,   1,   1), thread idx:   7, cord: (  4,   6)
block idx: (  1,   1,   1), thread idx:   8, cord: (  5,   6)
block idx: (  1,   1,   1), thread idx:   9, cord: (  3,   7)
block idx: (  1,   1,   1), thread idx:  10, cord: (  4,   7)
block idx: (  1,   1,   1), thread idx:  11, cord: (  5,   7)
block idx: (  1,   1,   1), thread idx:  12, cord: (  3,   4)
block idx: (  1,   1,   1), thread idx:  13, cord: (  4,   4)
block idx: (  1,   1,   1), thread idx:  14, cord: (  5,   4)
block idx: (  1,   1,   1), thread idx:  15, cord: (  3,   5)
block idx: (  1,   1,   1), thread idx:  16, cord: (  4,   5)
block idx: (  1,   1,   1), thread idx:  17, cord: (  5,   5)
block idx: (  1,   1,   1), thread idx:  18, cord: (  3,   6)
block idx: (  1,   1,   1), thread idx:  19, cord: (  4,   6)
block idx: (  1,   1,   1), thread idx:  20, cord: (  5,   6)
block idx: (  1,   1,   1), thread idx:  21, cord: (  3,   7)
block idx: (  1,   1,   1), thread idx:  22, cord: (  4,   7)
block idx: (  1,   1,   1), thread idx:  23, cord: (  5,   7)
block idx: (  0,   1,   1), thread idx:   0, cord: (  3,   4)
block idx: (  0,   1,   1), thread idx:   1, cord: (  4,   4)
block idx: (  0,   1,   1), thread idx:   2, cord: (  5,   4)
block idx: (  0,   1,   1), thread idx:   3, cord: (  3,   5)
block idx: (  0,   1,   1), thread idx:   4, cord: (  4,   5)
block idx: (  0,   1,   1), thread idx:   5, cord: (  5,   5)
block idx: (  0,   1,   1), thread idx:   6, cord: (  3,   6)
block idx: (  0,   1,   1), thread idx:   7, cord: (  4,   6)
block idx: (  0,   1,   1), thread idx:   8, cord: (  5,   6)
block idx: (  0,   1,   1), thread idx:   9, cord: (  3,   7)
block idx: (  0,   1,   1), thread idx:  10, cord: (  4,   7)
block idx: (  0,   1,   1), thread idx:  11, cord: (  5,   7)
block idx: (  0,   1,   1), thread idx:  12, cord: (  3,   4)
block idx: (  0,   1,   1), thread idx:  13, cord: (  4,   4)
block idx: (  0,   1,   1), thread idx:  14, cord: (  5,   4)
block idx: (  0,   1,   1), thread idx:  15, cord: (  3,   5)
block idx: (  0,   1,   1), thread idx:  16, cord: (  4,   5)
block idx: (  0,   1,   1), thread idx:  17, cord: (  5,   5)
block idx: (  0,   1,   1), thread idx:  18, cord: (  3,   6)
block idx: (  0,   1,   1), thread idx:  19, cord: (  4,   6)
block idx: (  0,   1,   1), thread idx:  20, cord: (  5,   6)
block idx: (  0,   1,   1), thread idx:  21, cord: (  3,   7)
block idx: (  0,   1,   1), thread idx:  22, cord: (  4,   7)
block idx: (  0,   1,   1), thread idx:  23, cord: (  5,   7)
block idx: (  1,   0,   0), thread idx:   0, cord: (  0,   0)
block idx: (  1,   0,   0), thread idx:   1, cord: (  1,   0)
block idx: (  1,   0,   0), thread idx:   2, cord: (  2,   0)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 之 MediaPlayer 播放音频与视频

本节引言&#xff1a; 本节带来的是Android多媒体中的——MediaPlayer&#xff0c;我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件&#xff0c;通过该类&#xff0c;我们可以以最小的步骤来获取&#xff0c;解码 和播放音视频。它支持三种不同的…

Android 14重要更新预览

Android 14重要更新预览 国际化 Android 14 在 Android 13 的基础上进一步扩展了按应用设定语言功能&#xff0c;提供了一些额外的功能&#xff1a; 自动生成应用的 localeConfig&#xff1a;从 Android Studio Giraffe Canary 7 和 AGP 8.1.0-alpha07 开始&#xff0c;您可以…

分布式限流方案及实现

优质博文&#xff1a;IT-BLOG-CN 一、限流的作用和意义 限流是对高并发访问进行限制&#xff0c;限速的过程。通过限流来限制资源&#xff0c;可以提高系统的稳定性和可靠性&#xff0c;控制系统的负载&#xff0c;削峰填谷&#xff0c;保证服务质量。 服务限流后的常见处理…

【论文笔记】KDD2019 | KGAT: Knowledge Graph Attention Network for Recommendation

Abstract 为了更好的推荐&#xff0c;不仅要对user-item交互进行建模&#xff0c;还要将关系信息考虑进来 传统方法因子分解机将每个交互都当作一个独立的实例&#xff0c;但是忽略了item之间的关系&#xff08;eg&#xff1a;一部电影的导演也是另一部电影的演员&#xff09…

【React】关于组件之间的通讯

&#x1f31f;组件化&#xff1a;把一个项目拆成一个一个的组件&#xff0c;为了便与开发与维护 组件之间互相独立且封闭&#xff0c;一般而言&#xff0c;每个组件只能使用自己的数据&#xff08;组件状态私有&#xff09;。 如果组件之间相互传参怎么办&#xff1f; 那么就要…

[nlp] TF-IDF算法介绍

&#xff08;1&#xff09;TF是词频(Term Frequency) 词频是文档中词出现的概率。 &#xff08;2&#xff09; IDF是逆向文件频率(Inverse Document Frequency) 包含词条的文档越少&#xff0c;IDF越大。

Maven依赖管理

依赖特性&#xff1a; 1、依赖配置 2、依赖传递 3、可选依赖 4、排除依赖 5、依赖范围

linux(centos) docker 安装 nginx

​1、拉取nginx最新版本镜像 docker pull nginx:latest 查看镜像 docker images 或者 docker images -a 2.启动nginx容器 docker run -d -p 80:80 --name nginx nginx 使用docker run命令&#xff0c;启动nginx容器。 --name&#xff0c;设置容器名。为方便记忆&#xff…

监控数据的采集方式及原理

1、读取 /proc 目录 /proc 是一个位于内存中的伪文件系统&#xff0c;该目录下保存的不是真正的文件和目录&#xff0c;而是一些“运行时”信息&#xff0c;Linux 操作系统层面的很多监控数据&#xff0c;比如内存数据、网卡流量、机器负载等&#xff0c;都是从 /proc 中获取的…

设计模式-中介者模式在Java中使用示例-客户信息管理

场景 欲开发客户信息管理窗口界面&#xff0c;界面组件之间存在较为复杂的交互关系&#xff1a;如果删除一个客户&#xff0c; 要在客户列表(List)中删掉对应的项&#xff0c;客户选择组合框(ComboBox)中客户名称也将减少一个&#xff1b; 如果增加一个客户信息&#xff0c;…

接口自动化代码不会写?试试RunnerGo

RunnerGo支持自动化测试功能&#xff0c;RunnerGo的工作流程是&#xff1a;接口管理-场景管理-性能测试-自动化测试&#xff0c;所以自动化测试的运行内容为场景下的用例&#xff0c;我们可以在“场景管理”中预先配置好该场景下的用例&#xff0c;也可以在自动化测试中创建用例…

Tensorflow benchmark 实操指南

环境搭建篇见环境搭建-CentOS7下Nvidia Docker容器基于TensorFlow1.15测试GPU_东方狱兔的博客-CSDN博客 1. 下载Benchmarks源码 从 TensorFlow 的 Github 仓库上下载 TensorFlow Benchmarks&#xff0c;可以通过以下命令来下载 https://github.com/tensorflow/benchmarks 我…

如何使用大模型处理生活繁琐的工作

如果每封电子邮件、每个带有订单、发票、投诉、录用请求或工作申请的 PDF 都可以翻译成机器可读的数据&#xff0c;会怎样&#xff1f;然后可以由 ERP / CRM / LMS / TMS 自动处理吗&#xff1f;无需编程特殊接口。 听起来很神奇&#xff1f;它确实有一些魔力。但最近已成为可…

【计算机视觉中的 GAN 】 - 生成学习简介(1)

一、说明 在阅读本文之前&#xff0c;强烈建议先阅读预备知识&#xff0c;否则缺乏必要的推理基础。本文是相同理论GAN原理的具体化范例&#xff0c;阅读后有两个好处&#xff1a;1 巩固了已经建立的GAN基本概念 2 对具体应用的过程和套路进行常识学习&#xff0c;这种练习题一…

3D Web轻量化渲染开发工具HOOPS Communicator是什么?

HOOPS Communicator是Tech Soft 3D旗下的主流产品之一&#xff0c;具有强大的、专用的高性能图形内核&#xff0c;是一款专注于基于Web端的高级3D工程应用程序。由HOOPS Server和HOOPS Web Viewer两大部分组成&#xff0c;提供了HOOPS Convertrer、Data Authoring的模型转换和编…

对模版以及模版中参数的理解

所谓模板&#xff0c;实际上是建立一个通用函数或类&#xff0c;其类内部的类型和函数的形参类型不具体指定&#xff0c;用一个虚拟的类型来代表。 就比方说你想要实现 一个Add的加法函数&#xff0c;面对不同的类型&#xff0c;你是否要进行多次函数重载呢&#xff0c;其实这多…

HCIP——前期综合实验

前期综合实验 一、实验拓扑二、实验要求三、实验思路四、实验步骤1、配置接口IP地址2、交换机配置划分vlan10以及vlan203、总部分部&#xff0c;骨干网配置OSPF分部总部骨干网 4、配置BGP建立邻居关系总部骨干网分部 5、发布用户网段6、将下一跳改为本地7、允许AS重复8、重发布…

计算机图形学笔记2-Viewing 观测

观测主要解决的问题是如何把物体的三维“模型”变成我们在屏幕所看到的二维“图片”&#xff0c;我们在计算机看到实体模型可以分成这样几步&#xff1a; 相机变换(camera transformation)或眼变换(eye transformation)&#xff1a;想象把相机放在任意一个位置来观测物体&#…

Electron + Vue3 + Vite + TS 构建桌面应用

之前是使用React、Electron、TS和webpack来构建桌面应用的。虽然功能齐全,但是打包等等开发的体验不太理想,总感觉太慢了。作为一个开发者,我们总是希望,执行构建命令后,可以快速打包或者启动本地应用,且通过更少的配置,来完成开发体验。 现在的vite已经得到广泛的应用…

Linux操作系统学习,Linux基础命令大全

目录 第一章、Linux简介和安装1.1&#xff09;Linux简介和分类1.2&#xff09;安装VMware虚拟机&#xff0c;在虚拟机中安装CentOS 7 第二章、虚拟机中Linux的IP地址配置详解2.1&#xff09;什么是IP地址&#xff0c;如何查看2.2&#xff09;虚拟机NAT模式中Linux的IP地址设置有…