繁体   English   中英

CUDA内核融合如何提高GPU上的内存绑定应用程序的性能?

CUDA How Does Kernel Fusion Improve Performance on Memory Bound Applications on the GPU?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我一直在研究流数据集,该流数据集大于GPU上用于设备进行基本计算的内存。 主要限制之一是以下事实:PCIe总线通常限制在8GB / s左右,并且内核融合可以帮助重用可以重用的数据,并且可以利用GPU中的共享内存和局部性。 我发现的大多数研究论文都很难理解,并且大多数都在诸如https://ieeexplore.ieee.org/document/6270615之类的复杂应用程序中实现了融合。 我读过许多论文,它们都无法解释将两个内核融合在一起的一些简单步骤。

我的问题是融合实际上是如何工作的? 将普通内核更改为融合内核需要执行哪些步骤? 另外,有必要使用多个内核来融合它,因为融合只是消除某些内存绑定问题以及利用局部性和共享内存的一个很好的名词。

我需要了解如何将内核融合用于基本CUDA程序,例如矩阵乘法或加减内核。 一个非常简单的示例(代码不正确,但应该给出一个想法),例如:

int *device_A;
int *device_B;
int *device_C;

cudaMalloc(device_A,sizeof(int)*N);

cudaMemcpyAsync(device_A,host_A, N*sizeof(int),HostToDevice,stream);

KernelAdd<<<block,thread,stream>>>(device_A,device_B); //put result in C
KernelSubtract<<<block,thread,stream>>>(device_C);

cudaMemcpyAsync(host_C,device_C, N*sizeof(int),DeviceToHost,stream); //send final result through the PCIe to the CPU
1 个回复

内核融合的基本思想是将2个或更多内核转换为1个内核。 操作被合并。 最初,好处是什么可能并不明显。 但是它可以提供两种相关的好处:

  1. 通过重用内核可能已在寄存器或共享内存中填充的数据
  2. 通过减少(即消除)“多余”的负载和存储

让我们使用像您这样的示例,其中我们有一个加法内核和一个乘法内核,并假设每个内核都在矢量上工作,并且每个线程都执行以下操作:

  1. 从全局内存中加载向量A的元素
  2. 向我的向量元素添加常量或乘以常量
  3. 将我的元素存储回向量A(在全局内存中)

此操作需要每个线程读取一次,每个线程写入一次。 如果我们都背靠背地完成了这两个操作,则操作序列将如下所示:

添加内核:

  1. 从全局内存中加载向量A的元素
  2. 向我的矢量元素添加值
  3. 将我的元素存储回向量A(在全局内存中)

乘以内核:

  1. 从全局内存中加载向量A的元素
  2. 我的向量元素乘以一个值
  3. 将我的元素存储回向量A(在全局内存中)

我们可以看到,第一个内核中的步骤3和第二个内核中的步骤1所做的事情实际上并不需要达到最终结果,但是由于这些(独立)内核的设计,它们是必需的。 一个内核无法通过全局存储器将结果传递给另一个内核。

但是,如果我们将两个内核结合在一起,我们可以这样编写一个内核:

  1. 从全局内存中加载向量A的元素
  2. 向我的矢量元素添加值
  3. 我的向量元素乘以一个值
  4. 将我的元素存储回向量A(在全局内存中)

此融合内核同时执行这两个操作,并产生相同的结果,但是它不需要2个全局内存加载操作和2个全局内存存储操作,而是每个操作仅需要1个。

对于GPU上的内存绑定操作(如此类操作)而言,这种节省可能非常重要。 通过减少所需的装载和存储数量,通常可以与减少装载/存储操作数量成比例地改善整体性能。

2 如何确定CUDA GPU性能?

我正在编写一个 cuda 程序,用于匹配分辨率 ~180X180 的每个输入图像,以及大约 10,000 个分辨率 ~128*128 的模板图像。 目标是实现实时性能,即在 1 秒内对 25~30 个输入图像(每个具有 10,000 个模板)进行模板匹配。 目前我正在使用以下方法 在 GPU ...

3 内存泄漏如何提高性能

我正在构建一个充满节点的大型RTree(空间索引)。 它需要能够处理许多查询和更新。 对象不断被创建和销毁。 我正在运行的基本测试是随着树中对象数量的增加而看到树的性能。 我插入100-20000一致大小,随机定位的对象,增量为100.搜索和更新与我目前面临的问题无关。 现在,当不 ...

4 如何优化Cuda内核性能?

我正在构建一个粒子系统,并且在计算父级位置的cuda内核性能方面遇到困难。 内核的调用方式如下: device_particleCoordinates链接到OpenGL缓冲区,以便直接修改坐标。 性能不是很好,我认为这是由于内核调用所致。 是否有任何可能影响性能的明显错误 ...

5 如何在给定的GPU上执行CUDA内核?

我的机器上有两张NVIDIA卡。 我想在其中一个(例如,第二个)上执行CUDA内核。 ,在教程中,我没有找到用于内存分配和内核执行的设备选择,就像针对OpenCL所做的那样。 您不能告诉我,我该如何选择视频设备来执行内核并在上面分配内存? ...

2014-11-10 18:17:56 1 104   cuda
6 额外的GPU无法提高Tensorflow性能

我正在使用我的桌面配置测试tensorflow的标准基准,如下所示。 英特尔i7-7700k 华硕B250采矿版 16兆p106 32GB内存 Ubuntu 16.04 cuda 9.0和cudnn 7.1 已安装Tensorflow 1.10 ...

7 GPU上的CUDA内核调度程序

我正在编写一个CUDA内核调度程序。 调度程序获取Task指针的向量并将它们执行。 指针指向不同类型参数的KernelTask对象,以支持具有任意参数的内核。 有一个CPU版本的Scheduler和一个GPU版本。 CPU版本工作得很好。 它调用虚函数Task::start来执行内 ...

2016-06-20 12:15:15 1 593   c++/ cuda
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM