VS2017 CUDA编程学习5:CUDA并行执行-线程


VS2017 CUDA编程学习1:CUDA编程两变量加法运算
VS2017 CUDA编程学习2:在GPU上执行线程
VS2017 CUDA编程学习3:CUDA获取设备上属性信息
VS2017 CUDA编程学习4:CUDA并行处理初探 - 向量加法实现


前言

今天学习了CUDA编程中关于线程的知识,这里做下笔记并分享给大家。


1. 线程

CUDA并行执行具有分层结构。每次内核启动时可被切分成多个并行执行的块,每个块又可以进一步被切分成多个线程,这也就是我们常说的内核函数配置参数:块数以及每个块的线程数。

并行执行的方式有多种,可以启动多个并行的块,每个块启动1个线程;也可以启动1个块,这个块启动多个线程;一般用的最多的内核参数配置是启动多个并行的块,每个块也启动多个线程,但是设备中每个块可以启动的线程数量是有上限的(1024个线程),这点要尤其注意。

当启动多个并行块,每个块也启动多个线程时,在内核函数中线程索引计算公式:
线 程 索 引 = 当 前 块 线 程 索 引 ( t h r e a d I d x . x ) + 当 前 块 索 引 ( b l o c k I d x . x ) ∗ 每 块 线 程 数 ( b l o c k D i m . x ) 线程索引 = 当前块线程索引(threadIdx.x) + 当前块索引(blockIdx.x)* 每块线程数(blockDim.x) 线=线(threadIdx.x)+blockIdx.x线blockDim.x


2. 代码实现

#include <stdio.h>
#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>

#define N 10000

/*
Block0:		thread0		thread1		thread2
Block1:		thread0		thread1		thread2
Block2:		thread0		thread1		thread2
*/

__global__ void GpuAdd(int* d_a, int* d_b, int* d_c)
{
    
    
	//线程ID = 当前线程ID + 当前块ID*每块线程数
	int tid = threadIdx.x + blockIdx.x * blockDim.x;

	// 当N远大于设备线程总数时,通过while循环,步长为所有块的线程总数,这样一个线程就可以执行多个操作,最终达到总数N
	while (tid < N)
	{
    
    
		d_c[tid] = d_a[tid] + d_b[tid];

		// 循环步长: 每个块的线程数 * 块数
		tid += blockDim.x * gridDim.x;
	}
}

int main()
{
    
    
	//定义主机(CPU, h_)变量和设备(GPU, d_)变量
	int h_a[N], h_b[N], h_c[N];
	int *d_a, *d_b, *d_c;

	//在GPU设备上分配全局内存
	cudaMalloc(&d_a, N * sizeof(int));
	cudaMalloc(&d_b, N * sizeof(int));
	cudaMalloc(&d_c, N * sizeof(int));

	//初始化主机数组
	for (int i = 0; i < N; i++)
	{
    
    
		h_a[i] = 2 * i;
		h_b[i] = i;
	}

	//将主机内存数据拷贝到设备内存中
	cudaMemcpy(d_a, h_a, N * sizeof(int), cudaMemcpyHostToDevice);
	cudaMemcpy(d_b, h_b, N * sizeof(int), cudaMemcpyHostToDevice);

	//启动核函数
	GpuAdd << <512, 512 >> > (d_a, d_b, d_c);

	cudaMemcpy(h_c, d_c, N * sizeof(int), cudaMemcpyDeviceToHost);

	//保证所有内核线程都执行完成
	cudaDeviceSynchronize();

	int correct = 1;
	printf("Vector addition on GPU \n");
	for (int i = 0; i < N; i++)
	{
    
    
		if (h_a[i] + h_b[i] != h_c[i])
		{
    
    
			correct = 0;
			break;
		}
	}

	if (correct == 1)
	{
    
    
		printf("GPU has computed Sum Correctly!\n");
	}
	else
	{
    
    
		printf("There is an Error in GPU Computation\n");
	}

	//释放设备内存
	cudaFree(d_a);
	cudaFree(d_b);
	cudaFree(d_c);

	return 0;
}

总结

CUDA并行执行的线程知识介绍就到这里了,内容很少,但是很精,希望对大家有启发!

学习资料

《基于GPU加速的计算机视觉编程》

Guess you like

Origin blog.csdn.net/DU_YULIN/article/details/120732743