本帖经过多方整理,大多来自各路书籍《GPGPU编程技术》《cuda高性能》
 
1 gridblock都可以用三元向量来表示:
 
  grid的数组元素是block
  block的数组元素是grid
但是1.x计算能力的核心,grid的第三元必须为1.block的X和Y索引最大尺寸为512
 
2 通过__launch_bounds__(maxBlockSize,minBlocksPerMp)来限制每个block中最大的线程数,及每个多处理器上最少被激活的block数
 
3 SM streaming multiprocessor 多流处理器
   SP scalar processor cores 标量处理核心
 
一个Block中的所有线程在一个多处理器上面并发执行。当这个Block的所有线程执行完后,再激活其他等待的Block.一个多处理器上也可以执行多个block。但是一个block却不能拆分为多个处理器上面执行
 
对于同一个Block里面的线程:
    1 同一个Block里的线程可以被同步
    2 可以共同访问多处理器里的共享存储器
 
到2.x为止,多处理器 执行任务时,以32个并行线程为单位,称为一个wrap。
当以个block到来的时候,会被分成线程号连续的多个wrap,然后多处理器上的SIMT控制器以wrap为单位控制调度线程。所以block中的线程数要是以32的整数倍来设计,就不会出现空闲的SP。组织WARP的时候,从线程号最小的开始
 
4 各个存储器存储位置及作用 
 
5 寄存器放在SP中,如果溢出,会被放在设备处理器上面,发生严重滞后,影响性能。
  1. 1.0   4KB
  2. 2.0   16kb

 

 共享存储器位于SM中,大约两个时钟周期读写4B,静态分配 __shared__ int shared[16];
  1. 1.0   16KB
  2. 2.0   48kb
 
6 共享存储器,是以4个字节为单位的16个存储器组
 
  bank冲突:半个warp中的多线程访问的数组元素处于同一个bank时,访问串行化,发生冲突
  避免冲突:最多的数据类型是int、float等占用4个字节的类型
 
7线程设计
  

  1. float shared=data[base+tid];
  2. base访问的起始元素下标 tid线程号
  
如果要是char类型,每个元素占1个字节,就会冲突
  

  1. float shared = data[base+4*tid];
 
8 共享存储器广播访问:半个warp线程都访问一个数据
 
9 补白策略
  1. shared[tid]=global[tid];
  2.  
  3. int number = shared[tid*16];
  4. int nRow = tid/16;
  5. int nColumn = tid%16;
  6. shared[nColumn*17+nRow] = global[tid];
  7.  
  8. int number = shared[17*tid];

  

10 一次性访问全局存储器:数据的起始地址应为每个线程访问数据大小的16倍的整数倍
 
11 主机锁页存储器cudaHostMalloc()分配。
 
  不参与操作系统分页管理的存储空间,访问锁页文件不会耗费主机内存分页管理方面的开销。不会被操作系统放到硬盘的页面文件中,因此比访问普通的主机存储器更快。
 
 
12 计算能力2.x的GPU上面,每个SM有独立的一级缓存,有唯一的二级缓存
 
13 异步并发
 
主机上的计算、
设备上的计算、
主机到设备上的传输、
设备到主机上的传输共同执行
 
14 设备存储器 类型是DRAM,动态随机存储器。使用它最高效的方式就是顺序读取。为了保证顺序:
 
  1. __global__ static void sumof(int *pnNumber,int* pnResult,clock_t* pclock_tTime){
  2. const int tid = threadIdx.x;
  3. int nSum = 0;
  4. int i;
  5. clock_t clock_tStart;
  6. if(tid == 0) clock_tStart = clock();
  7.  
  8. for(i = tid;i<DATA_SIZE;i+=THREAD_NUM){
  9. nSum += pnNumber[i]*pnNumber[i];
  10. }
  11.  
  12. pnResult[tid] = nSum;
  13. if(tid == 0)
  14. *pclock_tTime = clock()-clock_tStart;
  15. }
每个block 在1.x的计算能力的GPU下,最多只有512的线程数

  1. __global__ static void sumof(int *pnNumber,int* pnResult,clock_t* pclock_tTime){
  2. const int tid = threadIdx.x;
  3. const int bid = blockIdx.x;
  4. int nSum = 0;
  5. int i;
  6. clock_t clock_tStart;
  7. if(tid == 0) pclock_tTime[bid] = clock();
  8.  
  9. for(i = bid*THREAD_NUM+tid;i<DATA_SIZE;i+=BLOCK_NUM*THREAD_NUM){
  10. nSum += pnNumber[i]*pnNumber[i];
  11. }
  12.  
  13. pnResult[bid*THREAD_NUM+tid] = nSum;
  14.  
  15. if(tid == 0)
  16. *pclock_tTime[bid+BLOCK_NUM] = clock();
  17. }

 

15 用缩减树避免bank冲突:
 
  bank冲突指的是,一个warp内的线程同时访问一个bank列,导致串行读取数据
 
  1. noffset = THREAD_NUM/2;
  2. while(noffset > 0){
  3. if(tid < offset)
  4. nshared[tid] += nshared[tid+noffset];
  5. }
  6. noffset >>= 1;
  7.  
  8. __syncthreads();

 

16 CPU有强大的分支预测、程序堆栈、循环优化等针对控制采取的复杂逻辑。
    GPU相对简单,适合处理顺序的,单一的,少循环,少跳转的语句。
 
17  #progma unroll 5下面的程序循环5次
 
18 cuda中的同步
 
1》__syncthreads()同步
 
  同一个warp内的线程总是被一同激活且一同被分配任务,因此不需要同步。因此最好把需要同步的线程放在同一个warp内,这样就减少了__syncthreads()的指令
 
2》__threadfence() __threadfence_block()同步
 
  前者针对grid的所有线程,后者针对block内的所有线程。告知线程,全局存储器或共享存储器已经被改变
 
3》cudaThreadSynchronize() 主机与设备间的同步
 
  在主机程序里同步线程。该函数以上的设备线程完成后,控制权才交给cpu
 
4》volatile关键字
 
  使用这个关键字定义数组,设备会知道这个数组随时都会改变,就会自动重新读取数组(但是不能保证线程间读取的数据一致)
 
 

cuda编程知识普及的更多相关文章

  1. CUDA编程

    目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...

  2. CUDA编程-(1)Tesla服务器Kepler架构和万年的HelloWorld

    结合CUDA范例精解以及CUDA并行编程.由于正在学习CUDA,CUDA用的比较多,因此翻译一些个人认为重点的章节和句子,作为学习,程序将通过NVIDIA K40服务器得出结果.如果想通过本书进行CU ...

  3. CUDA编程之快速入门

    CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要 ...

  4. CUDA 编程的基本模式

    reproduced from: http://www.cnblogs.com/muchen/p/6306747.html 前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式 ...

  5. CUDA编程之快速入门【转】

    https://www.cnblogs.com/skyfsm/p/9673960.html CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架 ...

  6. 【并行计算-CUDA开发】CUDA编程——GPU架构,由sp,sm,thread,block,grid,warp说起

    掌握部分硬件知识,有助于程序员编写更好的CUDA程序,提升CUDA程序性能,本文目的是理清sp,sm,thread,block,grid,warp之间的关系.由于作者能力有限,难免有疏漏,恳请读者批评 ...

  7. 57 CUDA 编程入门

    0 引言 由于毕设用到了Marvin,采用的是CUDA框架作为加速器,正好借此学习一下CUDA编程的一些基本知识. 各个版本的cuda的下载链接如下. https://developer.nvidia ...

  8. CUDA学习笔记-1: CUDA编程概览

    1.GPU编程模型及基本步骤 cuda程序的基本步骤如下: 在cpu中初始化数据 将输入transfer到GPU中 利用分配好的grid和block启动kernel函数 将计算结果transfer到C ...

  9. 不同版本CUDA编程的问题

    1 无法装上CUDA的toolkit 卸载所有的NVIDIA相关的app,包括NVIDIA的显卡驱动,然后重装. 2之前的文件打不开,one or more projects in the solut ...

随机推荐

  1. L2-005. 集合相似度(set使用)

    L2-005. 集合相似度 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定两个整数集合,它们的相似度定义为:Nc/Nt*1 ...

  2. 转:MySQL Row Format(MySQL行格式详解)

    MySQL Row Format(MySQL行格式详解) --转载自登博的博客

  3. Excel开发学习笔记:读取xml文件及csv文件

    遇到一个数据处理自动化的问题,于是打算开发一个基于excel的小工具.在业余时间一边自学一边实践,抽空把一些知识写下来以备今后参考,因为走的是盲人摸象的野路子,幼稚与错误请多包涵. ).Split(  ...

  4. Java学习之系统高可用性渲染接口日志自动服务降级

    背景:公司都追求系统的高可用性,这里不可用时间就是其中很重要的一个指标,为此在做系统功能升级迭代的过程中如何快速处理异常恢复正常功能极为重要.现在对新增模块的要求是都增加开关,方便快速关闭异常模块,但 ...

  5. python-xlrd 实现excel 导入数据

    首先安装 xlrd 两种方式: 1.wheel 方式 安装: 首先要下载 wheel :

  6. [MySQL]表创建外键失败:ERROR 1005 (HY000): Can't create table (errno: 150)

    在数据库中建立一个新表(表引擎为InnoDB)时, 需要用到外键, 所以就在建表的时候加了一句foreign key (column) references table_name.但是执行时出现 ER ...

  7. webscheduler 开源定时服务和延迟服务

    源码地址:https://gitee.com/eabeat/webscheduler 架构上采用 asp.net + access ,实现简单的管理界面,可以维护调用API,查看日志等功能.内核采用Q ...

  8. Python之函数目录(自定义函数,内置函数,装饰器,迭代器,生成器)

    1.初始函数 2.函数嵌套及作用域 3.装饰器 4.迭代器和生成器 6.内置函数 7.递归函数 8.匿名函数 9.函数相关定义 10.三元表达式.列表推导式.生成器表达式 11.函数与方法的区别  

  9. MySessionFactory

    package com.ORM; import org.hibernate.HibernateException; import org.hibernate.Session; import org.h ...

  10. 前端seo小结,网页代码优化

    seo的目的:提高网站流量 search engine optimization 搜索引擎优化seo search engine marketing 搜索引擎营销sem 权重10个等级 等级越大,权重 ...