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的负载均衡策 ...
- Modelbuilder进阶教程
Modelbuilder进阶教程 By 李远祥 Modelbuilder 进阶1 自定义变量 参数是用来交互操作的,因此,参数具备非常大的灵活性,包括参数的定义和调用. 除了工具里面的参数之外,还可以 ...
- CSS3知识点整理(三)----变形与动画
一.CSS3中的变形 1)旋转 rotate() rotate()函数通过指定的角度参数使元素相对原点进行旋转. 它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度. 如果这个值为正值,元 ...
- 关于JavaScript中的编码和解码函数
js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent 1 ...
- nginx配合IIS实现简单负载均衡
1.IIS 部署两个站点端口分别为8081和8082 8081站点和8082站点如下[随便写了个没有样式的很丑的页面],我特意加了111和222区分 2.设置nginx配置文件,实现简单的负载 ...
- 安装grub
安装windows后,grub不见了 先安装Neo进入Linux 两条命令搞定. 在root用户下输入: update-grub grub-install /dev/sda
- 初识Html:Html和CSS的关系
学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的: 1. HTML是网页内容的载体.内容就是网页制作者放在页面上想要让用户 ...
- SVN的具体使用方法介绍(安装以及操作)
今天由于项目的需要安装了SVN,在这里和大家分享一下SVN安装的详细过程和分享一些资料. (1)首先是客户端的安装. 1)获取客户端安装包. --安装包的获取路径: TortoiseSVN的官方下载地 ...
- 部署lamp
- Spring框架---Spring入门
Spring入门 为了能更好的理解先讲一些有的没的的东西: 什么是Spring Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架 分层 SUN提供的EE的三层结构 ...