《cuda c编程权威指南》04 - 使用块和线程索引映射矩阵索引

目录

[1. 解决的问题](#1. 解决的问题)

[2. 分析](#2. 分析)

[3. 方法](#3. 方法)

[4. 代码示例](#4. 代码示例)


1. 解决的问题

利用块和线程索引,从全局内存中访问指定的数据。

2. 分析

通常情况下,矩阵 是用行优先的方法在全局内存中线性存储的。如下。

8列6行矩阵(nx,ny)=(8,6)。

3. 方法

这里建立二维网格(2,3)+二维块(4,2)为例,使用其块和线程索引映射矩阵索引。

(1)第一步,可以用以下公式把线程和块索引映射到矩阵坐标上;

(2)第二步,可以用以下公式把矩阵坐标映射到全局内存中的索引/存储单元上;

比如要获取矩阵元素(col,row) = (2,4) ,其全局索引是34,映射到矩阵坐标上,

ix = 2 + 0*3=2; iy = 0 + 2*2=4. 然后再映射到全局内存idx = 4*8 + 2 = 34.

4. 代码示例

cpp 复制代码
#include "cuda_runtime.h"
#include "device_launch_parameters.h"  // threadIdx

#include <stdio.h>    // io
#include <time.h>     // time_t
#include <stdlib.h>  // rand
#include <memory.h>  //memset


#define CHECK(call)                                   \
{                                                     \
    const cudaError_t error_code = call;              \
    if (error_code != cudaSuccess)                    \
    {                                                 \
        printf("CUDA Error:\n");                      \
        printf("    File:       %s\n", __FILE__);     \
        printf("    Line:       %d\n", __LINE__);     \
        printf("    Error code: %d\n", error_code);   \
        printf("    Error text: %s\n",                \
            cudaGetErrorString(error_code));          \
        exit(1);                                      \
    }                                                 \
}


void initiaInt(int* p, const int N)
{

	for (int i = 0; i < N; i++)
	{
		p[i] = i;
	}
}

/// <summary>
/// 
/// </summary>
/// <param name="c">全局内存中线性存储的二维矩阵</param>
/// <param name="nx">列</param>
/// <param name="ny"></param>
void printMatrix(int* c, const int nx, const int ny)
{
	int* ic = c;
	printf("\n matrix: [%d, %d] \n", nx, ny);
	for (int i = 0; i < ny; i++)
	{
		for (int j = 0; j < nx; j++)
		{
			int cur_ele = ic[i * nx + j];
			printf("%d ", cur_ele);
		}
		printf("\n");
	}
	printf("\n");
}

/// <summary>
/// 
/// </summary>
/// <param name="a">全局内存中是线性存储的</param>
/// <param name="nx">col</param>
/// <param name="ny"></param>
/// <returns></returns>
__global__ void printThreadIdx(int* a, const int nx, const int ny)
{
	// 矩阵行列
	int ix = threadIdx.x + blockIdx.x * blockDim.x;
	int iy = threadIdx.y + blockIdx.y * blockDim.y;  
	// 全局索引
	unsigned int idx = iy * nx + ix;  // 前面有iy行,每行有nx个数。
	printf("thread_idx (%d, %d) block_idx (%d, %d) coordinate (%d, %d) global index %d val %d\n",
		threadIdx.x, threadIdx.y, blockIdx.x, blockIdx.y, ix, iy, idx, a[idx]
	);
}


int main(void)
{
	// get device info
	int device = 0;
	cudaDeviceProp deviceProp;
	CHECK(cudaGetDeviceProperties(&deviceProp, device));
	printf("Using device: %d %s", device, deviceProp.name);  // 卡号0的显卡名称。
	CHECK(cudaSetDevice(device));  // 设置显卡号

	// set matrix dimension
	int nx = 8, ny =6, nxy = nx * ny;
	int nBytes = nxy * sizeof(int);

	// malloc host memory
	int* h_a;
	h_a = (int*)malloc(nBytes);

	// init data
	initiaInt(h_a, nxy);
	printMatrix(h_a, nx, ny);

	// malloc device memory
	int* d_Mat_a;
	cudaMalloc((void**)&d_Mat_a, nBytes);
	
	// transfer data from host to device
	cudaMemcpy(d_Mat_a, h_a, nBytes, cudaMemcpyHostToDevice);

	// config
	dim3 block(4, 2);  // 二维线程块(x,y)=(4,2)
	dim3 grid((nx+block.x-1) / block.x, (ny+block.y-1)/block.y); // 二维网格(2,3)
	// 直接nx/block.x = 8/4=2. (8+4-1)/4=2.
	
	// invoke kernel
	printThreadIdx << <grid, block >> > (d_Mat_a, nx, ny);
	cudaDeviceSynchronize();

	// free memory
	cudaFree(d_Mat_a);
	free(h_a);

	// reset device
	cudaDeviceReset();

	return 0;
}

可以看到,全局索引值就是矩阵中存储的值。

相关推荐
fpcc12 小时前
并行编程实战——CUDA编程的流的优先级
c++·cuda
碧海潮生_CC2 天前
【CUDA笔记】03 CUDA GPU 架构与一般的程序优化思路(下)
笔记·架构·cuda
中医正骨葛大夫3 天前
一文解决如何在Pycharm中创建cuda深度学习环境?
pytorch·深度学习·pycharm·软件安装·cuda·anaconda·配置环境
lvxiangyu118 天前
wsl2 ubuntu24 opengl 无法使用nvidia显卡 解决方法记录
wsl·cuda·opengl
李昊哲小课8 天前
wsl ubuntu24.04 cuda13 cudnn9 pytorch 显卡加速
人工智能·pytorch·python·cuda·cudnn
wanzhong23339 天前
CUDA学习2-CPU和GPU的性能优化
深度学习·gpu·cuda·高性能计算
碧海潮生_CC15 天前
【CUDA笔记】01-入门简介
笔记·cuda
喆星时瑜18 天前
关于 ComfyUI 的 Windows 本地部署系统环境教程(详细讲解Windows 10/11、NVIDIA GPU、Python、PyTorch环境等)
python·cuda·comfyui
安全二次方security²21 天前
CUDA C++编程指南(1)——简介
nvidia·cuda·c/c++·device·cuda编程·architecture·compute unified
千年奇葩1 个月前
Unity性能优化之:利用CUDA加速Unity实现大规模并行计算。从环境搭建到实战案例
c++·人工智能·unity·游戏引擎·cuda