CUDA多个流的使用
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多个流的使用的更多相关文章
- CUDA 7 Stream流简化并发性
CUDA 7 Stream流简化并发性 异构计算是指高效地使用系统中的所有处理器,包括 CPU 和 GPU .为此,应用程序必须在多个处理器上并发执行函数. CUDA 应用程序通过在 streams ...
- CUDA中的流与事件
流:CUDA流很像CPU的线程,一个CUDA流中的操作按顺序进行,粗粒度管理多个处理单元的并发执行. 通俗的讲,流用于并行运算,比如处理同一副图,你用一个流处理左边半张图片,再用第二个流处理右边半张图 ...
- 【CUDA 基础】6.5 流回调
title: [CUDA 基础]6.5 流回调 categories: - CUDA - Freshman tags: - 流回调 toc: true date: 2018-06-20 21:56:1 ...
- 【CUDA 基础】6.1 流和事件概述
title: [CUDA 基础]6.1 流和事件概述 categories: - CUDA - Freshman tags: - 流 - 事件 toc: true date: 2018-06-10 2 ...
- 【CUDA 基础】6.0 流和并发
title: [CUDA 基础]6.0 流和并发 categories: - CUDA - Freshman tags: - 流 - 事件 - 网格级并行 - 同步机制 - NVVP toc: tru ...
- CUDA从入门到精通
http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...
- CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET CUDA ...
- CUDA C Programming Guide 在线教程学习笔记 Part 10【坑】
▶ 动态并行. ● 动态并行直接从 GPU 上创建工作,可以减少主机和设备间数据传输,在设备线程中调整配置.有数据依赖的并行工作可以在内核运行时生成,并利用 GPU 的硬件调度和负载均衡.动态并行要求 ...
- CUDA Samples: Streams' usage
以下CUDA sample是分别用C++和CUDA实现的流的使用code,并对其中使用到的CUDA函数进行了解说,code参考了<GPU高性能编程CUDA实战>一书的第十章,各个文件内容如 ...
随机推荐
- [AngularJS] Interpolation fail in IE 11
When you occured this problem, check few things: For the input field, use // Use ng-attr-placeholder ...
- UITextField用法
.创建 .UITextField* textField = [[UITextField alloc]initWithFrame:CGRectMake(, , , )]; .设置委托 //委托类需要遵守 ...
- 【MongoDB】在Mongodb使用shell实现与javascript的动态交互
关于利用mongodb的shell运行脚本,这点在曾经的文章中有点遗漏:如今在此篇博客中做个补充: 一.在命令行中传入脚本文件 定义一个javasciprt文件,名称为:script1.js,内容例如 ...
- Tomcat结合Apache、Nginx实现高性能的web服务器
一.Tomcat为什么需要与apache.nginx一起结合使用? Tomcat虽然是一个servlet和jsp容器,但是它也是一个轻量级的web服务器.它既可以处理动态内容,也可以处理静态内容.不过 ...
- RSA公钥、私钥、签名和验签
1 RSA加密算法介绍 RSA又叫非对称加密算法,这类加密算法有一对秘钥,其中一个用来加密一个用来解密.这一对秘钥中你可以选择一个作为私钥(自己保存),另一个作为公钥(对外公开).用私钥加密的内容只能 ...
- 怎样用O2O去改变充满谎言、疑虑和愤慨的维修行业
为什么千亿级的维修服务市场出不了行业巨头? 据相关统计,我国的整个维修服务市场规模可达每年数千亿元之巨(当中仅家电维修就可达近千亿规模,更遑论手机.数码.家具等维修). 相同是千亿级规模的服务行业 ...
- 检测dll是32/64位?(直接读dll文件包含的某几个字节进行判断)
检查dll是32位还是64位? #include "stdafx.h" #include <Windows.h> int _tmain(int argc, _TCHAR ...
- mysql使用substring_index达到splite功能
函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...
- 在nginx中使用lua直接訪问mysql和memcaced达到数据接口的统一
安装nginx參见<nginx+lua+redis构建高并发应用> 让nginx 中的nginx_lua_module支持mysql 和memcache 下载 https://github ...
- Linux下iptables屏蔽IP和端口号
http://blog.csdn.net/kobejayandy/article/details/24332597 iptables 屏蔽端口