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

中国最大的网站制作公司百度安装到桌面

中国最大的网站制作公司,百度安装到桌面,怎样在网站是做宣传,wordpress大转盘【CUDA】CUDA 基本概念和 Hierarchy CUDA 编程基础:Host 和 Device 工作流程 首先简单介绍CUDA 编程的基本概念:讲解 Host(CPU)与 Device(GPU)的区别、内存管理以及 CUDA 运行时的工作机制。 Host&#x…

【CUDA】CUDA 基本概念和 Hierarchy

CUDA 编程基础:Host 和 Device 工作流程

首先简单介绍CUDA 编程的基本概念:讲解 Host(CPU)与 Device(GPU)的区别、内存管理以及 CUDA 运行时的工作机制。


Host(主机) vs. Device(设备)

  • Host(CPU)
    • 执行通用代码(无需 CUDA 扩展)。
    • 使用主板上的 RAM 作为内存。
    • 运行标记为 __host__ 的函数。
  • Device(GPU)
    • 进行高效并行计算。
    • 使用 GPU 自带的 VRAM(视频内存、显存)。
    • 运行标记为 __global____device__ 的函数。

CUDA 程序运行流程

  1. 将数据从 Host 复制到 Device:使用 cudaMemcpy 传输输入数据到 GPU 的显存。
  2. 加载并执行 CUDA 内核:
    • 使用 GPU 并行执行内核函数(__global__)。
    • 内核函数处理传入的变量并完成计算。
  3. 将结果从 Device 复制回 Host:将处理后的数据从显存复制回主机内存。

CUDA 命名约定

  • 变量命名:
    • h_A:Host(CPU)上的变量,例如 A
    • d_A:Device(GPU)上的变量,例如 A
  • 函数修饰符:
    • __global__:GPU 上的内核函数,可以由 CPU 调用。它通常不返回值,而是通过修改传入的变量完成操作,例如矩阵乘法。
    • __device__:只能由 GPU 调用,用于在内核函数中执行特定任务。它类似于调用库函数,但只能在 GPU 内部执行。
    • __host__:只能在 CPU 上执行,与普通的 C/C++ 函数相似。

CUDA 内存管理

  • 显存分配: 使用 cudaMalloc 在显存中分配内存。

    float *d_a, *d_b, *d_c;
    cudaMalloc(&d_a, N * N * sizeof(float));
    cudaMalloc(&d_b, N * N * sizeof(float));
    cudaMalloc(&d_c, N * N * sizeof(float));
    
  • 内存拷贝: 使用 cudaMemcpy 在 Host 和 Device 间传输数据:

    • Host → Device(CPU → GPU):cudaMemcpyHostToDevice
    • Device → Host(GPU → CPU):cudaMemcpyDeviceToHost
    • Device → Device(GPU 内部或不同 GPU 之间):cudaMemcpyDeviceToDevice
  • 释放显存: 使用 cudaFree 释放分配的显存。

    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_c);
    

CUDA 编译器(nvcc)

  • Host 代码
    • 被修改以支持 CUDA 内核。
    • 编译为普通的 x86 二进制。
  • Device 代码
    • 编译为 PTX(并行线程执行)代码。
    • PTX 是跨 GPU 代的稳定中间表示,通过 JIT(即时编译)转为本地 GPU 指令,实现向前兼容。

CUDA 的并行计算模型是基于层次化的线程结构设计的,这种设计为大规模并行计算提供了高效管理线程的方式。以下是 CUDA 的核心层次结构:


层次结构概览

  1. Kernel:
    • 定义:CUDA 程序的核心计算函数,运行在 GPU 上。
    • 工作方式:通过网格 (Grid) 和块 (Block) 的组织方式来并行化任务。
  2. Thread:
    • 定义:GPU 的基本执行单元,每个线程独立运行。
    • 特性:每个线程有自己的寄存器和局部内存空间。
  3. Thread Block (Block):
    • 定义:线程的逻辑分组,一个 Block 包含若干个线程。
    • 重要性:Block 是 CUDA 的调度单元,提供线程间共享的共享内存。
    • 限制:每个 Block 中的线程数量有上限,通常是 1024 个线程(具体依赖于 GPU 架构)。
  4. Grid (网格):
    • 定义:Block 的逻辑分组,一个 Grid 包含若干个 Block。
    • 重要性:通过组织多个 Block 实现大规模并行任务。

CUDA 的工作流

  1. 用户定义一个 Kernel 函数,用于描述 GPU 上的计算。
  2. 调用时通过 <<<Grid, Block>>> 来指定 Grid 和 Block 的规模。
  3. GPU 硬件会为每个线程分配一个唯一的索引,这些索引用于访问内存和分配任务。

4 个核心术语

这4个变量都是内置变量,由编译器自动提供,供核函数使用。

1. gridDim ⇒ 网格的维度
  • 定义gridDim 定义了 Grid 在每个维度上的 Block 数量。

  • 类型:3D 变量,gridDim.x, gridDim.y, gridDim.z

  • 用途:决定网格规模,帮助计算全局索引。

  • 示例:

    dim3 grid(4, 3);  // 4 个 Block 在 X 方向,3 个 Block 在 Y 方向
    printf("Grid dimensions: %d x %d\n", gridDim.x, gridDim.y);
    

2. blockIdx ⇒ Block 的索引
  • 定义blockIdx 标识当前线程所属 Block 在 Grid 中的索引。

  • 类型:3D 变量,blockIdx.x, blockIdx.y, blockIdx.z

  • 用途:结合线程索引计算全局索引。

  • 范围[0, gridDim.{x|y|z} - 1]

  • 示例:

    int block_index = blockIdx.x;  // 当前 Block 在 X 方向的索引
    

3. blockDim ⇒ Block 的维度
  • 定义blockDim 表示每个 Block 在每个维度上的线程数量。

  • 类型:3D 变量,blockDim.x, blockDim.y, blockDim.z

  • 用途:用于定义 Block 内线程的局部索引范围。

  • 范围:由 Kernel 配置时的第二个参数决定。

  • 示例:

    dim3 block(16, 16);  // 每个 Block 包含 16x16 个线程
    printf("Block dimensions: %d x %d\n", blockDim.x, blockDim.y);
    

4. threadIdx ⇒ 线程的索引
  • 定义threadIdx 表示当前线程在所在 Block 中的索引。

  • 类型:3D 变量,threadIdx.x, threadIdx.y, threadIdx.z

  • 用途:配合 blockIdxblockDim 计算全局线程索引。

  • 范围[0, blockDim.{x|y|z} - 1]

  • 示例:

    int thread_index = threadIdx.x;  // 当前线程在 X 方向的索引
    

可以网格是由多个小长方体(block)组成的一个大长方体(grid),其中小长方体又是由多个更小的长方体(thread)组成。


线程束 (Warp)

定义
  • 线程束(Warp) 是 CUDA 调度的基本单元,每个 Warp 包含 32 个线程
  • Warp 内的线程以 SIMD(单指令多数据) 模式运行:所有线程执行相同指令,但操作的数据可以不同。

线程束的特性
  1. 执行同步
    • 一个 Warp 内的所有线程在同一个时钟周期内执行同一条指令。
  2. 线程束分歧 (Warp Divergence)
    • 如果 Warp 内的线程需要执行不同的分支(例如 if/else),Warp 会被拆分成多个子任务,依次完成分支,导致性能下降。
  3. 调度单位
    • Warp 是 CUDA 的硬件调度单位。一个 Block 中的线程数量如果不是 32 的倍数,会浪费部分调度资源。完整代码示例

实例

#include <stdio.h>__global__ void Whoami(void){int block_id = blockIdx.x + blockIdx.y * gridDim.x +blockIdx.z * gridDim.x * gridDim.y;int block_offset = block_id * blockDim.x * blockDim.y * blockDim.z;int thread_offset = threadIdx.x + threadIdx.y * blockDim.x +threadIdx.z * blockDim.x * blockDim.y;int id = block_offset + thread_offset;printf("%04d | Block(%d %d %d) = %3d | Thread(%d %d %d) = %3d\n",id, blockIdx.x, blockIdx.y, blockIdx.z, block_id,threadIdx.x, threadIdx.y, threadIdx.z, thread_offset);
}int main(int argc,char** argv){const int b_x = 2, b_y = 3, b_z = 4;const int t_x = 4, t_y = 4, t_z = 4;int blocks_per_grid = b_x * b_y * b_z;int threads_per_block = t_x * t_y * t_z;printf("%d block/grid\n", blocks_per_grid);printf("%d threads/block\n", threads_per_block);printf("%d total threads\n", blocks_per_grid * threads_per_block);dim3 blocksPerGrid(b_x, b_y, b_z);dim3 threadsPerBlock(t_x, t_y, t_z);Whoami<<<blocksPerGrid, threadsPerBlock>>>();cudaDeviceSynchronize();return 0;
}

这段代码展示了如何使用 gridDimblockIdxblockDimthreadIdx 来理解grid,block,thread的层级结构。通过输出你也会看到线程束 (Warp)的表现,block中的线程按32分为了两部分,所以同一个block的输出被分为了两部分。

参考:https://github.com/Infatoshi/cuda-course/tree/master/05_Writing_your_First_Kernels

http://www.15wanjia.com/news/19986.html

相关文章:

  • 什么网站可以做告白的网页北京网站推广排名
  • 佛山免费网站制作台湾搜索引擎
  • 建设通怎么样性价比高的seo网站优化
  • 运城哪家做网站的公司好百度seo优化推广
  • 如何用电脑记事本做网站seo创业
  • 深圳做网站网络营销公司山西seo优化公司
  • 北京做网络优化的公司seo优化网站百度技术
  • 济南做网站的公司能让手机流畅到爆的软件
  • 海阳市住房和城乡建设局官方网站视频互联网推广选择隐迅推
  • 做公司网站都需要什么资料百度售后电话人工服务
  • 中国10大品牌装修公司上海seo推广服务
  • 长沙企业网站建设公网站免费建站app
  • 安徽房地产网站建设百度指数批量查询
  • html前端网站开发PPT网络营销软件排行
  • wordpress在线阅读pdf网站优化排名技巧
  • 领域网站建设seo外包推广
  • 怎么在ps做网站首页建立网站需要什么
  • 网站无法添加图片百度推广助手官方下载
  • 网站建设企业推荐广西网站建设制作
  • 多备份 wordpress网站内容seo
  • 什么是网站建设需求谷歌搜索引擎入口2022
  • 阜新百姓网免费发布信息关键词排名优化工具
  • 建站模板怎么选seo 优化技术难度大吗
  • 行政单位单位网站建设温州seo结算
  • 网站制作加盟营销推广渠道
  • 有哪些网站是用vue做的可口可乐软文营销案例
  • 网站如何调用数据库seo软件资源
  • 行业门户网站模板百度快速排名技术培训教程
  • 衢州网站建设专业的公司泰州百度关键词优化
  • 网站开发费用计入什么二级科目电脑零基础培训班