cuda编程学习3——VectorSum
这个程序是把两个向量相加
add<<<N,1>>>(dev_a,dev_b,dev_c);//<N,1>,第一个参数N代表block的数量,第二个参数1代表每个block中thread的数量
tid=blockIdx.x;//blockIdx是一个内置变量,blockIdx.x代表这是一个2维索引
下面对这个程序做几个变化,并指出相应的程序应该改变的地方:
1.若启动1个block,每个block中有N个线程。改变:
add<<<1,N>>>(dev_a,dev_b,dev_c);
tid=threadIdx.x
2.此程序N的大小为10,N是向量的大小,若N更大呢?硬件对线程块的数量是有限制的,对每个线程块中线程的数量也是有限制的,可以通过运行deviceQuery进行查看,我是NVIDIA Geforce 750Ti,cuda7.5,线程块数量不能超过65535,每个线程块中线程的数量不能超过1024。若所求的向量中元素大于最多能启动的线程块数量和每个线程块中最大线程数量呢?改变:
add<<<m,n>>>(dev_a,dev_b,dev_c)//m为启动的block数量,n为每个block中thread数量
tid=threadIdx.x+blockIdx.x*blockDim.x;//blockDim是一个内置变量,保存的是线程块中每一维的线程的数量
注意:m应该=N/n,但是若n不能整除N呢?答案:m=(N+n-1)/n,即为大于或等于N的n的最小倍数
3.若向量大小N大于总的可启动线程数量(最大block数量×block中最大thread数量)呢?改变:
add<<<128,1024>>>(dev_a,dev_b,dev_c);
tid=threadIdx.x+blockIdx.x*blockDim.x;
while(tid<N)
{
c[tid]=a[tid]+b[tid];
tid+=blockDim.x*gridDim.x;
}
注意:此处启动了128个block,每个block有1024个thread,用户可以更改这个值,此处只是以<128,1024>为例。
tid+=blockDim.x*gridDim.x;一次循环,执行的线程数量为blockDim.x*gridDim.x,即线程块大小×线程块数量。
代码:
/*
============================================================================
Name : VectorSum-CUDA.cu
Author : can
Version :
Copyright : Your copyright notice
Description : CUDA compute reciprocals
============================================================================
*/
#include<iostream>
using namespace std;
#define N 10
__global__ void add(int *a,int *b,int *c);
static void checkCudaErrorAux(const char *,unsigned, const char *,cudaError_t);
#define CUDA_CHECK_RETURN(value) checkCudaErrorAux(__FILE__,__LINE__,#value,value)
int main()
{
int a[N],b[N],c[N];
int *dev_a,*dev_b,*dev_c;
for(int i=0;i<N;i++)
{
a[i]=i;
b[i]=i*i;
}
CUDA_CHECK_RETURN(cudaMalloc((void **)&dev_a,N*sizeof(int)));
CUDA_CHECK_RETURN(cudaMalloc((void **)&dev_b,N*sizeof(int)));
CUDA_CHECK_RETURN(cudaMalloc((void **)&dev_c,N*sizeof(int)));
CUDA_CHECK_RETURN(cudaMemcpy(dev_a,a,N*sizeof(int),cudaMemcpyHostToDevice));
CUDA_CHECK_RETURN(cudaMemcpy(dev_b,b,N*sizeof(int),cudaMemcpyHostToDevice));
add<<<N,1>>>(dev_a,dev_b,dev_c);//<N,1>,第一个参数N代表block的数量,第二个参数1代表每个block中thread的数量
CUDA_CHECK_RETURN(cudaMemcpy(c,dev_c,N*sizeof(int),cudaMemcpyDeviceToHost));
for(int j=0;j<N;j++)
{
cout<<a[j]<<" + "<<b[j]<<" = "<<c[j]<<endl;
}
return 0;
}
__global__ void add(int* a,int* b,int* c)
{
int tid=blockIdx.x;//blockIdx是一个内置变量,blockIdx.x代表这是一个2维索引
if(tid<N)//避免出错造成非法内存访问
{
c[tid]=a[tid]+b[tid];
}
}
static void checkCudaErrorAux(const char *file,unsigned line, const char *statement,cudaError_t error)
{
if(error==cudaSuccess)
{
return;
}
cout<<statement<<"returned:"<<cudaGetErrorString(error)<<" at file:"<<file<<" line:"<<line<<endl;
exit(1);
}
cuda编程学习3——VectorSum的更多相关文章
- CUDA编程学习笔记1
CUDA编程模型是一个异构模型,需要CPU和GPU协同工作. host和device host和device是两个重要的概念 host指代CPU及其内存 device指代GPU及其内存 __globa ...
- CUDA编程学习相关
1. CUDA编程之快速入门:https://www.cnblogs.com/skyfsm/p/9673960.html 2. CUDA编程入门极简教程:https://blog.csdn.net/x ...
- CUDA编程学习(一)
/****c code****/ #include<stdio.h> int main() { printf("Hello world!\n); ; } /****CUDA co ...
- cuda编程学习6——点积dot
__shared__ float cache[threadPerBlock];//声明共享内存缓冲区,__shared__ __syncthreads();//对线程块中的线程进行同步,只有都完成前面 ...
- cuda编程学习5——波纹ripple
/共有DIM×DIM个像素,每个像素对应一个线程dim3 blocks(DIM/16,DIM/16);//2维dim3 threads(16,16);//2维kernel<<<blo ...
- cuda编程学习4——Julia
书上的例子编译会有错误,修改一下行即可. __device__ cuComplex(float a,float b):r(a),i(b){} /* ========================== ...
- cuda编程学习2——add
cudaMalloc()分配的指针有使用限制,设备指针的使用限制总结如下: 1.可以将其传递给在设备上执行的函数 2.可以在设备代码中使用其进行内存的读写操作 3.可以将其传递给在主机上执行的函数 4 ...
- cuda编程学习1——hello world!
将c程序最简单的hello world用cuda编写在GPU上执行,以下为代码: #include<iostream>using namespace std;__global__ void ...
- CUDA编程学习笔记2
第二章 cuda代码写在.cu/.cuh里面 cuda 7.0 / 9.0开始,NVCC就支持c++11 / 14里面绝大部分的语言特性了. Dim3 __host__ __device__ dim3 ...
随机推荐
- Dubbo源码学习--集群负载均衡算法的实现
相关文章: Dubbo源码学习文章目录 前言 Dubbo 的定位是分布式服务框架,为了避免单点压力过大,服务的提供者通常部署多台,如何从服务提供者集群中选取一个进行调用, 就依赖Dubbo的负载均衡策 ...
- IOS9.0 之后友盟分享详细过程
一: 申请友盟的AppKey(友盟的Key是根据应用的名称生成的!) 在友盟注册了你自己的开发者账号后就可以申请AppKey了.然后在这个方法里面设置Key - (BOOL)application:( ...
- 提升iOS审核通过率之“IPv6兼容测试”
作者:jingle 腾讯系统测试工程师 商业转载请联系腾讯WeTest授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/285.html 一.背景 在 ...
- 在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】
前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优 ...
- [JAVA] - Java OutOfMemoryError分类
Java OutOfMemoryError一般常遇到的分为两类,分别提示: "Java heap space" 和 "PermGen space",前面的是指j ...
- 事件详解<一>
一 扭转对事件的认知 事件,是js和html交互的桥梁.当用户操作页面上的元素,比如点击,鼠标移入移出,然后做一些事情. 你若触发,我便执行--事件发生,调用它的处理函数执行相应的JavaScript ...
- 细谈sass和less中的变量及其作用域
博客原文地址:Claiyre的个人博客 https://claiyre.github.io/ 博客园地址:http://www.cnblogs.com/nuannuan7362/ 如需转载,请在文章开 ...
- [译]如何在Web开发中使用Python
[译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...
- xml中的SQL注入
大家通常知道xml中大部分会导致外部实体注入,但是,xml也会出现SQL注入: 在xml中正常的sql语句写法有两种: 第一: <select id="selectById" ...
- 无需Get更多技能,快速打造一个可持久化的任务调度
项目总是很忙,忙里偷闲还是要总结一下,前一段时间,由于项目中需要,我们需要很多定时汇总数据的情况,项目初期主要使用sql server 计划任务实现对数据的汇总与统计,但是开发到一定时间内,需求提出了 ...