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. Dynamic device virtualization

    A system and method for providing dynamic device virtualization is herein disclosed. According to on ...

  2. [React Intl] Format Date and Time Using react-intl FormattedDate and FormattedTime

    Using the react-intl FormattedDate and FormattedTime components, we’ll render a JavaScript Date into ...

  3. 【习题 3-1 UVA - 1585】Score

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟水题 [错的次数] 在这里输入错的次数 [反思] 在这里输入反思 [代码] #include <bits/stdc++.h ...

  4. hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    ...

  5. js私有变量

    js私有变量 一.总结 1.在js函数中定义 this.name='张三'; (函数的属性)外部是可以访问的,但是 var name='张三'; (函数的私有变量),这样定义的话外部没有办法访问 2. ...

  6. keil出错总结

    错误一: ..\APP\app.c(51): error:  #268: declaration may not appear after executable statement in block ...

  7. php 发送QQ邮箱邮件

    这是我的源码比较简陋 https://www.lanzous.com/i2l7h8f 感谢 https://www.cnblogs.com/woider/p/6980456.html 下载phpmai ...

  8. php面试题5

    php面试题5 一.总结 二.php面试题5 1. 什么事面向对象?主要特征是什么?1) 面向对象是程序的一种设计方式,它利于提高程序的重用性,是程序结构更加清晰.2) 主要特征:封装.继承.多态 2 ...

  9. thinkphp3.2.3 小程序获取手机号 php 解密

    首先是把这个文件夹放到\ThinkPHP\Library\Org里面 //zll 根据加密字符串和session_key和iv获取手机号 /** * [getphone description] * ...

  10. Netty+WebSocket简单实现网页聊天

    基于Netty+WebSocket的网页聊天简单实现 一.pom依赖 <dependency>        <groupId>io.netty</groupId> ...