CUDA中使用多个流并行执行数据复制和核函数运算可以进一步提高计算性能。以下程序使用2个流执行运算:

#include "cuda_runtime.h"
#include <iostream>
#include <stdio.h>
#include <math.h> #define N (1024*1024)
#define FULL_DATA_SIZE N*20 __global__ void kernel(int* a, int *b, int*c)
{
int threadID = blockIdx.x * blockDim.x + threadIdx.x; if (threadID < N)
{
c[threadID] = (a[threadID] + b[threadID]) / 2;
}
} int main()
{
//获取设备属性
cudaDeviceProp prop;
int deviceID;
cudaGetDevice(&deviceID);
cudaGetDeviceProperties(&prop, deviceID); //检查设备是否支持重叠功能
if (!prop.deviceOverlap)
{
printf("No device will handle overlaps. so no speed up from stream.\n");
return 0;
} //启动计时器
cudaEvent_t start, stop;
float elapsedTime;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0); //创建两个CUDA流
cudaStream_t stream, stream1;
cudaStreamCreate(&stream);
cudaStreamCreate(&stream1); int *host_a, *host_b, *host_c;
int *dev_a, *dev_b, *dev_c;
int *dev_a1, *dev_b1, *dev_c1; //在GPU上分配内存
cudaMalloc((void**)&dev_a, N * sizeof(int));
cudaMalloc((void**)&dev_b, N * sizeof(int));
cudaMalloc((void**)&dev_c, N * sizeof(int)); cudaMalloc((void**)&dev_a1, N * sizeof(int));
cudaMalloc((void**)&dev_b1, N * sizeof(int));
cudaMalloc((void**)&dev_c1, N * sizeof(int)); //在CPU上分配页锁定内存
cudaHostAlloc((void**)&host_a, FULL_DATA_SIZE * sizeof(int), cudaHostAllocDefault);
cudaHostAlloc((void**)&host_b, FULL_DATA_SIZE * sizeof(int), cudaHostAllocDefault);
cudaHostAlloc((void**)&host_c, FULL_DATA_SIZE * sizeof(int), cudaHostAllocDefault); //主机上的内存赋值
for (int i = 0; i < FULL_DATA_SIZE; i++)
{
host_a[i] = i;
host_b[i] = FULL_DATA_SIZE - i;
} for (int i = 0; i < FULL_DATA_SIZE; i += 2 * N)
{
cudaMemcpyAsync(dev_a, host_a + i, N * sizeof(int), cudaMemcpyHostToDevice, stream);
cudaMemcpyAsync(dev_b, host_b + i, N * sizeof(int), cudaMemcpyHostToDevice, stream); cudaMemcpyAsync(dev_a1, host_a + i + N, N * sizeof(int), cudaMemcpyHostToDevice, stream1);
cudaMemcpyAsync(dev_b1, host_b + i + N, N * sizeof(int), cudaMemcpyHostToDevice, stream1); kernel << <N / 1024, 1024, 0, stream >> > (dev_a, dev_b, dev_c);
kernel << <N / 1024, 1024, 0, stream1 >> > (dev_a, dev_b, dev_c1); cudaMemcpyAsync(host_c + i, dev_c, N * sizeof(int), cudaMemcpyDeviceToHost, stream);
cudaMemcpyAsync(host_c + i + N, dev_c1, N * sizeof(int), cudaMemcpyDeviceToHost, stream1);
} // 等待Stream流执行完成
cudaStreamSynchronize(stream);
cudaStreamSynchronize(stream1); cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop); std::cout << "消耗时间: " << elapsedTime << std::endl; //输出前10个结果
for (int i = 0; i < 10; i++)
{
std::cout << host_c[i] << std::endl;
} getchar(); // free stream and mem
cudaFreeHost(host_a);
cudaFreeHost(host_b);
cudaFreeHost(host_c); cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c); cudaFree(dev_a1);
cudaFree(dev_b1);
cudaFree(dev_c1); cudaStreamDestroy(stream);
cudaStreamDestroy(stream1);
return 0;
}

使用2个流,执行时间16ms,基本上是使用一个流消耗时间的二分之一。

CUDA多个流的使用的更多相关文章

  1. CUDA 7 Stream流简化并发性

    CUDA 7 Stream流简化并发性 异构计算是指高效地使用系统中的所有处理器,包括 CPU 和 GPU .为此,应用程序必须在多个处理器上并发执行函数. CUDA 应用程序通过在 streams  ...

  2. CUDA中的流与事件

    流:CUDA流很像CPU的线程,一个CUDA流中的操作按顺序进行,粗粒度管理多个处理单元的并发执行. 通俗的讲,流用于并行运算,比如处理同一副图,你用一个流处理左边半张图片,再用第二个流处理右边半张图 ...

  3. 【CUDA 基础】6.5 流回调

    title: [CUDA 基础]6.5 流回调 categories: - CUDA - Freshman tags: - 流回调 toc: true date: 2018-06-20 21:56:1 ...

  4. 【CUDA 基础】6.1 流和事件概述

    title: [CUDA 基础]6.1 流和事件概述 categories: - CUDA - Freshman tags: - 流 - 事件 toc: true date: 2018-06-10 2 ...

  5. 【CUDA 基础】6.0 流和并发

    title: [CUDA 基础]6.0 流和并发 categories: - CUDA - Freshman tags: - 流 - 事件 - 网格级并行 - 同步机制 - NVVP toc: tru ...

  6. CUDA从入门到精通

    http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...

  7. CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET

    http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET CUDA ...

  8. CUDA C Programming Guide 在线教程学习笔记 Part 10【坑】

    ▶ 动态并行. ● 动态并行直接从 GPU 上创建工作,可以减少主机和设备间数据传输,在设备线程中调整配置.有数据依赖的并行工作可以在内核运行时生成,并利用 GPU 的硬件调度和负载均衡.动态并行要求 ...

  9. CUDA Samples: Streams' usage

    以下CUDA sample是分别用C++和CUDA实现的流的使用code,并对其中使用到的CUDA函数进行了解说,code参考了<GPU高性能编程CUDA实战>一书的第十章,各个文件内容如 ...

随机推荐

  1. 得到INI文件所有Section(所有节点名称)

    char SectionNames[MAX_PATH],*pSectionName; ZeroMemory(SectionNames,MAX_PATH); GetPrivateProfileSecti ...

  2. Mahout快速入门教程 分类: B10_计算机基础 2015-03-07 16:20 508人阅读 评论(0) 收藏

    Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现.分类.聚类等.Mahout最大的优点就是基于hadoop实现,把很多以前运行于单 ...

  3. 微信小程序 富文本插件 循环渲染方式

    感谢GitHub https://github.com/icindy/wxParse/wiki/wxParse%E5%A4%9A%E6%95%B0%E6%8D%AE%E5%BE%AA%E7%8E%AF ...

  4. 【38.02%】【codeforces 625B】War of the Corporations

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  5. HDOJ 5001 Walk

    概率DP dp[j][d] 表示不经过i点走d步到j的概率, dp[j][d]=sigma ( dp[k][d-1] * Probability ) ans = sigma ( dp[j][D] ) ...

  6. 指针知识梳理6-const与指针

    const 定义的变量为仅仅读变量.在语法层面上通过这个变量去改动内存是不同意的. 可是对于下面代码.就有非常多人绕了: const int  *p1;  //p1能变.*p1不能变 int cons ...

  7. php中foreach源码分析(编译原理)

    php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...

  8. Django表单上传

    任务描述:实现表单提交(上传文件) 1.项目目录: 2.源代码: regist.html <!DOCTYPE html> <html lang="en"> ...

  9. 谈谈JavaEE的mvc模式及典型的三层架构

    首先,向读者介绍一下mvc架构,mvc是一种源于桌面程序的架构模式,它的基本思想是把程序界面和业务逻辑分开,这样便于软件的后期维护,同时也方便开发时期分工及管理,mvc有很多有点所以现在已经被广泛的应 ...

  10. 微信开发学习日记(六):weiphp框架

    最近重点在看weiphp这个开源的第三方微信公众平台框架. 在网上找微信资料,找到了这个.很早之前,就初步学习了Thinkphp和Onethink2个开源框架,当看到weiphp是用这2个框架开发的时 ...