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,基本上是使用一个流消耗时间的二分之一。

最新文章

  1. ABP源码分析八:Logger集成
  2. javascript运动系列第五篇——缓冲运动和弹性运动
  3. c调用python
  4. 解决Cannot delete or update a parent row: a foreign key constraint fails (`current_source_products`.`product_storage`, CONSTRAINT `product_storage_ibfk_3` FOREIGN KEY (`InOperatorID`)
  5. 【函数】plsql 函数的默认值
  6. Linux 执行ll命令时指定按文件时间或大小排序
  7. 膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)
  8. 打破常规——大胆尝试在路由器上搭建SVN服务器
  9. Android版:验证手机号码的正则表达式
  10. 数据操作So easy-LINQ解析
  11. Kafka源码分析-序列2 -Producer
  12. 对plist文件的简单封装
  13. javascript:void(0)的作用示例
  14. 理解Babel是如何编译JS代码的及理解抽象语法树(AST)
  15. [HAOI2008]移动玩具 状压
  16. .NET Core之微信支付之公众号、H5支付篇
  17. AntV G6绘制流程图学习例子
  18. axis 数据流
  19. MD5=======RBAC权限管理
  20. Windows服务设置

热门文章

  1. chmod用数字来表示权限的方法
  2. C#学习笔记——常量、字段以及事件
  3. 学习C#修饰符:类修饰符和成员修饰符
  4. 3、应用层常用lib函数使用说明
  5. [转载]Surging 分布式微服务框架使用入门
  6. SoC编译HEX脚本(基于RISC-V的SoC)
  7. CSS垂直居中的实现
  8. 魔兽争霸war3心得体会(二):狗转蜘蛛,DK光环+游侠二发
  9. 【PHP】php 递归、效率和分析(转)
  10. [转载]Ocelot简易教程(一)Ocelot是什么