《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;
}

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

相关推荐
专注VB编程开发20年1 天前
CUDA实现随机切割算法,显卡多线程计算
算法·cuda
KIDGINBROOK5 天前
NVIDIA NCCL 源码学习(十七)- LL和LL128协议
cuda·rdma·nccl
老鱼说AI6 天前
大规模并发处理器程序设计(PMPP)讲解(CUDA架构):第四期:计算架构与调度
c语言·深度学习·算法·架构·cuda
HelloTonyGo6 天前
个人游戏笔记本免费“养龙虾”(二)用显卡GPU运行OpenClaw,CUDA的安装与配置
gpu·nvidia·cuda·openclaw
superior tigre6 天前
记录一次Segmentation fault (core dumped) 段错误(cuda编程)
cuda
老鱼说AI10 天前
CUDA架构与高性能程序设计:多维网格与数据
c++·人工智能·深度学习·神经网络·机器学习·语言模型·cuda
70asunflower11 天前
CUDA基础知识巩固检验练习题【附有参考答案】(8)
c++·人工智能·cuda
被制作时长两年半的个人练习生11 天前
blackwell和warp specialization的背景下如何理解CTA
gpu·cuda
70asunflower11 天前
CUDA基础知识巩固检验练习题【附有参考答案】(7)
c++·人工智能·cuda
money053412 天前
CUDA C++ Best Practices Guide读书笔记
cuda