[4]CUDA中的向量计算与并行通信模式

news2024/11/19 12:36:08

CUDA中的向量计算与并行通信模式

  • 本节开始,我们将利用GPU的并行能力,对其执行向量和数组操作
  • 讨论每个通信模式,将帮助你识别通信模式相关的应用程序,以及如何编写代码

1.两个向量加法程序

  • 先写一个通过cpu实现向量加法的程序
  • 如下所示,向量相加实际上是模仿GPU的写法,在GPU中,tid 代表特定的某个线程的ID。
  • 如果你的cpu是双核的,可以在每个核心上运行一个线程,分别将tid初始化为0和1,然后每次循环的时候+2,这样的话可以实现一个核激素那偶数元素的和,一个核计算基数元素的和,通过两个线程的实现并行计算
#include "stdio.h"
#include<iostream>
//Defining Number of elements in Array
#define N	5
//Defining vector addition function for CPU
void cpuAdd(int *h_a, int *h_b, int *h_c) {
	int tid = 0;	
	while (tid < N)
	{
		h_c[tid] = h_a[tid] + h_b[tid];
		tid += 1;
	}
}

int main(void) {
	int h_a[N], h_b[N], h_c[N];
		//Initializing two arrays for addition
	for (int i = 0; i < N; i++) {
		h_a[i] = 2 * i*i;
		h_b[i] = i;
	}
	//Calling CPU function for vector addition
	cpuAdd (h_a, h_b, h_c);
	//Printing Answer
	printf("Vector addition on CPU\n");
	for (int i = 0; i < N; i++) {
		printf("The sum of %d element is %d + %d = %d\n", i, h_a[i], h_b[i], h_c[i]);
	}
	return 0;
}

在这里插入图片描述

  • 而总所周知,NVIDIA GPU包含多个块,每个块又包含多个线程,因此可以通过GPU实现更多线程并行计算向量的和,最大程度提高速度
  • 可以将代码修改为核函数如下:
#include "stdio.h"
#include<iostream>
#include <cuda.h>
#include <cuda_runtime.h>

//Defining number of elements in Array
#define N	5

//Defining Kernel function for vector addition
__global__ void gpuAdd(int* d_a, int* d_b, int* d_c) {
	//Getting block index of current kernel
	int tid = blockIdx.x;	// handle the data at this index
	if (tid < N)
		d_c[tid] = d_a[tid] + d_b[tid];
}

int main(void) {

	//定义主机数组变量
	int h_a[N], h_b[N], h_c[N];

	//定义设备指针变量
	int* d_a, * d_b, * d_c;
	//分配显卡内存
	cudaMalloc((void**)&d_a, N * sizeof(int));
	cudaMalloc((void**)&d_b, N * sizeof(int));
	cudaMalloc((void**)&d_c, N * sizeof(int));
	//Initializing Arrays
	for (int i = 0; i < N; i++) {
		h_a[i] = 2 * i * i;
		h_b[i] = i;
	}
	// Copy input arrays from host to device memory
	cudaMemcpy(d_a, h_a, N * sizeof(int), cudaMemcpyHostToDevice);
	cudaMemcpy(d_b, h_b, N * sizeof(int), cudaMemcpyHostToDevice);

	//设置内核参数为5个块,每个块一个线程 ,并像核函数传递参数
	gpuAdd << <N, 1 >> > (d_a, d_b, d_c);

	//将计算结果从显卡拷贝到主机
	cudaMemcpy(h_c, d_c, N * sizeof(int), cudaMemcpyDeviceToHost);

	printf("Vector addition on GPU \n");
	//Printing result on console
	for (int i = 0; i < N; i++) {
		printf("The sum of %d element is %d + %d = %d\n", i, h_a[i], h_b[i], h_c[i]);
	}
	//Free up memory
	cudaFree(d_a);
	cudaFree(d_b);
	cudaFree(d_c);
	return 0;
}

在这里插入图片描述

  • 以上可以发现,通过GPU并行运算,或者多个线程的并行计算,明显的减少了数组的处理时间。比起CPU上的串行计算,提高了吞吐率
  • 在此说一下吞吐量的含义:只对网络、设备端口、虚电路或者其他设施,单位时间内成功的传送数据的数量(以比特、字节、分贝等测量)

2. 对比CPU代码和GPU代码的延迟

  • CPU的加法程序和GPU的加法程序都是以一个模块化的方式来编写的
  • N的值较小时,看不出cpu与GPU的差异,但是当N值很大时,会发现两者计算效率的显著差异
  • 下边将展示如何为并行计算计时并对两者时间进行比较
clock_t start_d = clock();
	printf("Doing GPU Vector add\n");
	gpuAdd << <N, 1 >> > (d_a, d_b, d_c);

	cudaThreadSynchronize();
	clock_t end_d = clock();
	double time_d = double(end_d - start_d) / CLOCKS_PER_SEC;
	printf("No of elements in Array: %d \n Device time %f second \n Host time %f second \n ",
		N, time_d, time_h);

3. 对向量的每个元素进行平方

  • 前边调用内核函数时启用了N个块,每个块一个线程执行计算;另一种也可以只启动1个块,块里边有N个线程,淡然也可以启用N个块,每个块M个线程
  • 下边通过启用一个块中的N个线程来执行向量每个元素的平方运算
#include "stdio.h"
#include<iostream>
#include <cuda.h>
#include <cuda_runtime.h>
//Defining number of elements in Array
#define N	5
//Kernel function for squaring number
__global__ void gpuSquare(float *d_in, float *d_out) {
	//Getting thread index for current kernel
	int tid = threadIdx.x;	// handle the data at this index
	float temp = d_in[tid];
	d_out[tid] = temp*temp;
}

int main(void) {
	//Defining Arrays for host
	float h_in[N], h_out[N];
	//Defining Pointers for device
	float *d_in, *d_out;

	// allocate the memory on the gpu
	cudaMalloc((void**)&d_in, N * sizeof(float));
	cudaMalloc((void**)&d_out, N * sizeof(float));
	//Initializing Array
	for (int i = 0; i < N; i++) {
		h_in[i] = i;
	}
	//Copy Array from host to device
	cudaMemcpy(d_in, h_in, N * sizeof(float), cudaMemcpyHostToDevice);
	//Calling square kernel with one block and N threads per block
	gpuSquare << <1, N >> >(d_in, d_out);
	//Coping result back to host from device memory
	cudaMemcpy(h_out, d_out, N * sizeof(float), cudaMemcpyDeviceToHost);
	//Printing result on console
	printf("Square of Number on GPU \n");
	for (int i = 0; i < N; i++) {
		printf("The square of %f is %f\n", h_in[i], h_out[i]);
	}
	//Free up memory
	cudaFree(d_in);
	cudaFree(d_out);
	return 0;
}

在这里插入图片描述

  • 需注意

    • 每当使用这种方式启动N个线程并行的时候,需要注意每个块的最大线程不超过 5121024
    • 现在所有计算能力/显卡算力在 3.0 - 7.5 的GPU卡,每个块最大1024个线程
    • 如果N是2000,而你的GPU卡线程的最大数量是512,那么不能写成 << <12 000 > >>,而应该使用<< <4,500 > >>,应该理性的选择合适数量的块和每个块具有的线程数量

4. 并行通信模式

  • 当多个线程并行执行时,它们遵循一定的通信模式,知道它们在显存里哪里输入,哪里输出

4.1 映射

  • 一对一操作,每个线程或任务读取单一输入,产生单一输出,就是Map模式
d_out[i] = d_in[i] * 2

4.2 收集

  • 此模式下,每个线程或者任务,具有多个输入,并产生单个输出,保存到存储器的单一位置,即Gather模式:
out[i] = (in[i-1] + in[i] + in[i+1]) / 3

4.3 分散式

  • Scatter 模式,线程或者任务读取单一输入,单项存储器产生多个输出,比如数组排序:
out[i-1] += 2 * in[i] and out[i+1] += 3 * in[i]

4.4 蒙版

  • 当线程或者任务要从数组中读取固定形状的相邻元素时,这叫stencil模式,在图像处理中非常有用。比如想用一个3X3或者5X5的窗口进行滑动滤波
  • 代码类似Gather

4.5 转置

  • 当想要输入矩阵行主序,输出矩阵想要列主序,或者有一个结构数组(SoA),想转换成一个数组结构(AoS),它是特别有用的。Transpose模式如下:
out[i+j*128] = in[j + i*128]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1683411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法刷题day52:区间DP

目录 引言一、石子合并二、环形石子合并三、能量项链四、加分二叉树 引言 关于区间DP&#xff0c;我其实觉得核心思想就是把一个区间拆分为任意两个区间&#xff0c;相当于是模拟枚举全部这种区间组合的过程&#xff0c;然后从中寻求最优解&#xff0c;本质上的思想不难&#…

PLC工程师按这个等级划分是否靠谱?

在工业自动化领域&#xff0c;PLC工程师扮演着至关重要的角色&#xff0c;他们负责构建、维护自动化系统&#xff0c;推动工业4.0进程的发展。成为一名优秀的PLC工程师需要经历不同境界的发展阶段&#xff0c;每个阶段都对应着不同的技能要求和责任。以下是PLC工程师的六种级别…

必应bing国内推广开户,全方位必应广告开户流程介绍!

在所有获客渠道中&#xff0c;搜索引擎广告成为企业扩大品牌影响力、精准触达目标客户的关键途径之一。作为全球领先的搜索引擎之一&#xff0c;必应&#xff08;Bing&#xff09;拥有庞大的用户群体和独特的市场优势&#xff0c;是企业不可忽视的营销阵地。云衔科技&#xff0…

声音转文本(免费工具)

声音转文本&#xff1a;解锁语音技术的无限可能 在当今这个数字化时代&#xff0c;信息的传递方式正以前所未有的速度进化。从手动输入到触控操作&#xff0c;再到如今的语音交互&#xff0c;技术的发展让沟通变得更加自然与高效。声音转文本&#xff08;Speech-to-Text, STT&…

微服务:利用RestTemplate实现远程调用

打算系统学习一下微服务知识&#xff0c;从今天开始记录。 远程调用 调用order接口&#xff0c;查询。 由于实现还未封装用户信息&#xff0c;所以为null。 下面我们来使用远程调用用户服务的接口&#xff0c;然后封装一下用户信息返回即可。 流程图 配置类中注入RestTe…

SAP销售手工发票录入

销售手工发票录入用于处理未启用 SD 模块标准处理流程的零星销售业务。 科目设置 收入类科目&#xff1a;设置税务类型&#xff0c;允许含税/不含税过账应收账款: 留空。其他应收款的设置类似 编辑选项设置 在中国&#xff0c;编辑选项一般设置为基于总额计税。使用事务码 FB…

Jenkins 构建 Web 项目:项目和服务器在一起的情况

构建的命令 node -v pnpm -v pnpm install pnpm build # 将dist打包成dist.zip zip -r dist.zip dist mv dist.zip /www/wwwroot/video.xxx.com/dist.zip cd /www/wwwroot/video.xxx.com # 解压并覆盖之前的文件 unzip -o dist.zip

期货学习笔记-横盘行情学习1

横盘行情的特征及分类 横盘行情的概念 横盘行情时中继形态的一种&#xff0c;一般常出现在大涨或大跌之后出现横盘行情是对当前趋势行情的修正&#xff0c;是对市场零散筹码的清理&#xff0c;是为了集中筹码更便于后期行情的展开 横盘行情的特征 1.水平运动&#xff1a;该…

1-4月我国5G用户、流量占比均过半,呈现平稳增长态势!

1-4月份&#xff0c;通信行业整体运行平稳。电信业务量收平稳增长&#xff1b;5G、千兆光网等新型基础设施建设持续推进&#xff0c;网络连接用户规模不断扩大&#xff0c;移动互联网接入流量较快增长。 一、总体运行情况 电信业务收入稳步增长&#xff0c;电信业务总量增速保持…

OpenAI宫斗剧番外篇: “Ilya与Altman联手对抗微软大帝,扫除黑恶势力”,“余华”和“莫言”犀利点评

事情是这样的。 小编我是一个重度的智谱清言用户&#xff0c;最近智谱清言悄悄上线了一个“划词引用”功能后&#xff0c;我仿佛打开了新世界的大门。我甚至用这个小功能&#xff0c;玩出来了即将为你上映的《OpenAI宫斗剧番外篇》。 3.5研究测试&#xff1a;hujiaoai.cn 4研…

别说废话!说话说到点上,项目高效沟通的底层逻辑揭秘

假设你下周要在领导和同事面前汇报项目进度&#xff0c;你会怎么做&#xff1f;很多人可能会去网上搜一个项目介绍模板&#xff0c;然后按照模板来填充内容。最后&#xff0c;汇报幻灯片做了 80 页&#xff0c;自己觉得非常充实&#xff0c;但是却被领导痛批了一顿。 这样的境…

番外篇 | YOLOv8改进之引入YOLOv9的RepNCSPELAN4模块 | 替换YOLOv8的C2f

前言:Hello大家好,我是小哥谈。YOLOv9,作为YOLO(You Only Look Once)系列的最新成员,代表着实时物体检测技术的又一重要里程碑。自YOLO系列算法诞生以来,它就以其出色的性能和简洁的设计思想赢得了广泛的关注和认可。从最初的YOLOv1到如今的YOLOv9,这个系列不断地进行技…

C++初阶学习第十弹——探索STL奥秘(五)——深入讲解vector的迭代器失效问题

vector&#xff08;上&#xff09;&#xff1a;C初阶学习第八弹——探索STL奥秘&#xff08;三&#xff09;——深入刨析vector的使用-CSDN博客 vector&#xff08;中&#xff09;&#xff1a;C初阶学习第九弹——探索STL奥秘&#xff08;四&#xff09;——vector的深层挖掘和…

二十五、openlayers官网示例CustomOverviewMap解析——实现鹰眼地图、预览窗口、小窗窗口地图、旋转控件

官网demo地址&#xff1a; Custom Overview Map 这个示例展示了如何在地图上增加一个小窗窗口的地图并跟随着地图的旋转而旋转视角。 首先加载了一个地图。其中 DragRotateAndZoom是一个交互事件&#xff0c;它可以实现按住shift键鼠标拖拽旋转地图。 const map new Map({int…

LSTM实例解析

大家好&#xff0c;这里是七七&#xff0c;今天带给大家的实例解析。以前也用过几次LSTM模型&#xff0c;但由于原理不是很清楚&#xff0c;因此不能清晰地表达出来&#xff0c;这次用LSTM的时候&#xff0c;去自习研究了原理以及代码&#xff0c;来分享给大家此次经历。 一、简…

《Python编程从入门到实践》day37

# 昨日知识点回顾 制定规范、创建虚拟环境并激活&#xff0c;正在虚拟环境创建项目、数据库和应用程序 # 今日知识点学习 18.2.4 定义模型Entry # models.py from django.db import models# Create your models here. class Topic(models.Model):"""用户学习的…

Vitis HLS 学习笔记--控制驱动TLP - Dataflow视图

目录 1. 简介 2. 功能特性 2.1 Dataflow Viewer 的功能 2.2 Dataflow 和 Pipeline 的区别 3. 具体演示 4. 总结 1. 简介 Dataflow视图&#xff0c;即数据流查看器。 DATAFLOW优化属于一种动态优化过程&#xff0c;其完整性依赖于与RTL协同仿真的完成。因此&#xff0c;…

微软开发者大会,Copilot Agents发布,掀起新一轮生产力革命!

把AI融入生产力工具的未来会是什么样&#xff1f;微软今天给出了蓝图。 今天凌晨&#xff0c;微软召开了Microsoft Build 2024 开发者大会&#xff0c;同前两天的Google I/O开发者大会一样&#xff0c;本次大会的核心词还是“AI”&#xff0c;其中最主要的内容是最新的Copilot…

如何提交网站到谷歌网站收录?

其实就那么几个步骤&#xff0c;要做谷歌那肯定是需要一个谷歌账号的&#xff0c;然后找到Google Search Console这个谷歌的官方平台&#xff0c;这是最权威的可以统计来自谷歌流量的平台了&#xff0c;毕竟是谷歌自家的&#xff0c;肯定也不可能作假&#xff0c;然后就是跟着平…

Kubernetes——Pod详解

目录 一、Pod基础概念 1.概念 2.使用方式 3.Pause容器 3.1网络 3.2存储 4.Pod容器分类 4.1自主式Pod 4.2控制器管理的Pod 二、Pod的分类 1.基础容器&#xff08;infrastructure container&#xff09; 2.初始化容器&#xff08;initcontainers&#xff09; 2.1Ini…