cuda中threadIdx、blockIdx、blockDim和gridDim的使用

news/2024/10/17 14:31:28/

一、直观的感觉线程、线程块、线程格

为了直观的感觉线程、线程块、线程格,画了下面一个示意图。分为了两部分,一部分为线程格,另一部分为线程块,在图中线程格和线程块都画成了3维的,实际也可以是一维或者二维的。其中线程格里面最小的单元为线程块,而一个线程块里面最小的单元为线程。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hCkKVuy-1638951262872)(C:\Users\13751\AppData\Roaming\Typora\typora-user-images\image-20211208154955182.png)]

二、threadIdx、blockIdx、blockDim和gridDim

可以把线程格和线程块都看作一个三维的矩阵。这里假设线程格是一个3*4*5的三维矩阵, 线程块是一个4*5*6的三维矩阵。

  1. gridDim

    gridDim.xgridDim.ygridDim.z分别表示线程格各个维度的大小,所以有

    gridDim.x=3
    gridDim.y=4
    gridDim.z=5
    
  2. blockDim
    blockDim.xblockDim.yblockDim.z分别表示线程块中各个维度的大小,所以有

    blockDim.x=4
    blockDim.y=5
    blockDim.z=6
    
  3. blockIdx

    blockIdx.xblockIdx.yblockIdx.z分别表示当前线程块所处的线程格的坐标位置

  4. threadIdx

    threadIdx.xthreadIdx.ythreadIdx.z分别表示当前线程所处的线程块的坐标位置

通过 blockIdx.xblockIdx.yblockIdx.zthreadIdx.xthreadIdx.ythreadIdx.z就可以完全定位一个线程的坐标位置了。

线程格里面总的线程个数N即可通过下面的公式算出

N = gridDim.x*gridDim.y*gridDim.z*blockDim.x*blockDim.y*blockDim.z

三、举例

将所有的线程排成一个序列,序列号为 0 , 1 , 2 , … , N 0,1,2,\dots,N 0,1,2,,N,如何找到当前的序列号?

  1. 先找到当前线程位于线程格中的哪一个线程块blockId

    blockId = blockIdx.x + blockIdx.y*gridDim.x + blockIdx.z*gridDim.x*gridDim.y;
    
  2. 找到当前线程位于线程块中的哪一个线程threadId

    threadId = threadIdx.x + threadIdx.y*blockDim.x + threadIdx.z*blockDim.x*blockDim.y;
    
  3. 计算一个线程块中一共有多少个线程M

    M = blockDim.x*blockDim.y*blockDim.z
    
  4. 求得当前的线程序列号idx

    idx = threadId + M*blockId;
    

下面是通过GPU并行计算实现的两个向量相减的例子

#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <stdio.h>
#include <stdlib.h>
#include <iostream>using namespace std;//block-thread 3D-3D
__global__ void testBlockThread9(int *c, const int *a, const int *b)
{int threadId_3D = threadIdx.x + threadIdx.y*blockDim.x + threadIdx.z*blockDim.x*blockDim.y;int blockId_3D = blockIdx.x + blockIdx.y*gridDim.x + blockIdx.z*gridDim.x*gridDim.y;int i = threadId_3D + (blockDim.x*blockDim.y*blockDim.z)*blockId_3D;c[i] = b[i] - a[i];
}void addWithCuda(int *c, const int *a, const int *b, unsigned int size)
{int *dev_a = 0;int *dev_b = 0;int *dev_c = 0;cudaSetDevice(0);cudaMalloc((void**)&dev_c, size * sizeof(int));cudaMalloc((void**)&dev_a, size * sizeof(int));cudaMalloc((void**)&dev_b, size * sizeof(int));cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);uint3 s1; s1.x = 5; s1.y = 2; s1.z = 2;uint3 s2; s2.x = size / 200; s2.y = 5; s2.z = 2;testBlockThread9<<<s1, s2 >>>(dev_c, dev_a, dev_b);cudaMemcpy(c, dev_c, size*sizeof(int), cudaMemcpyDeviceToHost);cudaFree(dev_a);cudaFree(dev_b);cudaFree(dev_c);cudaGetLastError();
}int main()
{const int n = 1000;int *a = new int[n];int *b = new int[n];int *c = new int[n];int *cc = new int[n];for (int i = 0; i < n; i++){a[i] = rand() % 100;b[i] = rand() % 100;c[i] = b[i] - a[i];}addWithCuda(cc, a, b, n);FILE *fp = fopen("out.txt", "w");for (int i = 0; i < n; i++)fprintf(fp, "%d %d\n", c[i], cc[i]);fclose(fp);bool flag = true;for (int i = 0; i < n; i++){if (c[i] != cc[i]){flag = false;break;}}if (flag == false)printf("no pass");elseprintf("pass");cudaDeviceReset();delete[] a;delete[] b;delete[] c;delete[] cc;getchar();return 0;
}

http://www.ppmy.cn/news/191442.html

相关文章

cuda中的blockIdx,threadIdx,blockDim以及gridDim的使用

转载于&#xff1a;DSP Tian的博客 threadIdx是一个uint3类型&#xff0c;表示一个线程的索引。 blockIdx是一个uint3类型&#xff0c;表示一个线程块的索引&#xff0c;一个线程块中通常有多个线程。 blockDim是一个dim3类型&#xff0c;表示线程块的大小。 gridDim是一个dim3…

win10 + NVIDIA GeForce RTX 2080 Ti + CUDA10.0 + cuDNN v7.6.5

win10 NVIDIA GeForce RTX 2080 Ti CUDA10.0 cuDNN v7.6.5 配置教程 参考文献&#xff1a; 本文参考了一下文献&#xff1a; 显卡驱动版本号一定要与cuda版本号想对应,要不然tensorflow运行会报错&#xff1a; https://blog.csdn.net/qxqsunshine/article/details/9690195…

tensorflow2.10.0+CUDA11.2+cuDNN8.1 for cuda11.2

下载前记得查看tensorflow-gpu与CUDA、cuDNN对应的版本 https://tensorflow.google.cn/install/source_windows?hl=en#gpu tensorflow-gpu2.10.0 pip install tensorflow-gpu 后面也可以跟上对应的版本号,如果下载失败可能是网不好,多试几次,也可以找找其他教程。 CUD…

Geforce GTX 1660Ti + Ubuntu18.04 LTS + Nvidia显卡驱动 +CUDA10 配置安装

一、安装环境介绍 操作系统&#xff1a;Ubuntu 18.04.2 LTS 系统内核&#xff1a;linux-image-4.18.0-25-generic CPU&#xff1a;Intel Core i7-9750H 独立显卡&#xff1a;Geforce GTX 1660Ti 二、安装Nvidia显卡驱动 sudo apt remove --purge nvidia* …

dig命令笔记

dig 命令全称域信息搜索器&#xff0c;是一个用于查询 DNS 域名服务器信息的命令行工具。因为dig命令灵活&#xff0c;容易使用&#xff0c;多数DNS管理员使用dig命令来诊断 DNS 问题。 dig 常用命令格式 dig [server] [-p port] [-t type] [-4] [-6] [trace] name 指定 DNS …

ubuntu 18.04 RTX2080(ti) --- tensorflow-gpu + cuda9.0 + cudnn-9.0 (ubuntu 16.04, TITAN XP)

0.下载display driver、cuda和cudnn RTX2080 Display Driver cuda cudnn 版本对应关系 1. 禁止系统默认的显卡驱动 打开系统黑名单 sudo gedit /etc/modprobe.d/blacklist.conf将下列代码填入文件末尾 # for nvidia display driver install blacklist vga16fb blacklist n…

dig命令的介绍与使用

dig命令的使用 Reference&#xff1a; 1.Linux下解析域名命令-dig 命令使用详解 2.ubuntu/debian下安装使用dig 3.dig命令详解 一、基本介绍 dig&#xff08;domain information group&#xff09;是常用的域名查询工具&#xff0c;可以从DNS域名服务器查询主机地址信息&…

win10 安装dig工具与使用dig命令

文章目录 1、安装dig2、添加环境变量3、使用dig windows dig工具的安装与使用 Dig 工具全称为域名信息搜索器&#xff08;Domain Information Groper&#xff09;&#xff0c;能够显示详细的DNS查询过程&#xff0c;是一个非常强大的DNS故障诊断工具。一般Linux和Unix系统都已内…