zoukankan      html  css  js  c++  java
  • 《大规模并行处理器编程实战》前十章

    ▶ P46。SPMD (Single-Program Multiple-Data) 单程序多数据,CUDA使用的并行编程风格。并行处理单元在数据的多个部分执行相同程序,但这些处理单元不用同时执行限购通的指令;SIMD (Single-Instruction Multiple-Data) 单指令多数据,SM 对 warps 使用的调度方式,所有并行处理单元在任何时候都执行相同的指令。

    ▶ P87。内存变量类型:

    变量类型 前缀名 声明位置 存储器 作用域 生命周期 说明
    全局变量 (__global__) 核函数外 全局存储器 网格 程序 被整个Grid和CPU使用,访问速度很慢
    数组以外的自动变量
    (__local__) 核函数内 寄存器 线程 核函数调用 若从全局内存中产生副本,则速度很慢
    数组自动变量 (__local__) 核函数内 局部存储器 线程 核函数调用
    共享内存变量 __shared__ 核函数内、外均可   线程块 核函数调用 线程块共享,被同一线程快中的所有线程同时读写
    常量内存变量 __constant__ 核函数外 常数存储器 网格 程序 从CPU中赋值后GPU可读不可写

    常量内存加速原理:半线程束广播(临近内存集合整体读取);不存在缓存一致性问题,可以放入 L1 缓存;GPU缓存易命中

    运行速度比较,__constant__ > __local__ > __share__ >>__global__ >> host memory

    ▶ 有关线程和线程块的层次与坐标计算

     1 Device ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
     2 含多个 Grid,一次核函数调用看作一个 Grid
     3 
     4     Grid 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━至多 65535 个 Block,至多三维
     5         指定方法:
     6         一维可用 unsigned int a;
     7         一般可用 dim3 blocksize(x) 或 dim3 blocksize(x, y) 或 dim3 blocksize(x, y, z);
     8         或直接在核函数调用时使用 dim3(x) 或 dim3(x, y) 或 dim3(x, y, z);
     9 
    10         下标范围
    11         一维:blockIdx.x,取值范围 [0, gridDim.x - 1]
    12         二维:blockIdx.x 和 blockIdx.y,取值范围 [0, gridDim.x - 1], [0 ~gridDim.y - 1]
    13         三维:blockIdx.x 和 blockIdx.y 和 blockIdx.z,取值范围 [0, gridDim.x - 1], [0, gridDim.y - 1], [0, gridDim.z - 1]
    14 
    15         Block 1 ━━━━━━━━━━━━━━━━至多1024个Thread,至多三维
    16             指定方法:
    17             一维可用 unsigned int a;
    18             一般可用 dim3 threadsize(x) 或 dim3 threadsize(x, y) 或 dim3 threadsize(x, y, z);
    19             或直接在核函数调用时使用 dim3(x) 或 dim3(x, y) 或 dim3(x, y, z);
    20             
    21             下标范围
    22             一维:threadIdx.x,取值范围 [0, blockDim.x - 1]
    23             二维;threadIdx.x 和 threadIdx.y,取值范围 [0, blockDim.x - 1], [0, blockDim.y - 1]
    24             三维;threadIdx.x 和 threadIdx.y 和 threadIdx.z,取值范围 [0, blockDim.x - 1] 和 [0, blockDim.y - 1], [0, blockDim.z - 1]
    25 
    26             Thread 1 ━━━━━━━━按照block、thread编号进行偏移:
    27                 一维:
    28                     id = blockIdx.x * blockDim.x + threadIdx.x;
    29                 跳转:
    30                     id += gridDim.x * blockDim.x;
    31                     在同一个 thread 中跨步吞吐更多的索引,跨步等于一次核函数调用时所有线程块的线程总数
    32 
    33                 二维:
    34                     idx = blockIdx.x * blockDim.x + threadIdx.x;
    35                     idy = blockIdx.y * blockDim.y + threadIdx.y;
    36                     id = idy * gridDim.x * blockDim.x + idx;
    37                     行 (x) 优先存储,列 (y) 在高位上(y相邻的元素存储位置不相邻)
    38                 跳转:
    39                     id += gridDim.x * gridDim.y * blockDim.x * blockDim.y;
    40                 
    41                 三维:
    42                     idx = blockIdx.x * blockDim.x + threadIdx.x;
    43                     idy = blockIdx.y * blockDim.y + threadIdx.y;
    44                     idz = blockIdx.z * blockDim.z + threadIdx.z; 
    45                     id = (idz * gridDim.y * blockDim.y + idy) * gridDim.x * blockDim.x + idx;
    46                     层 (z) 在最高位上
    47                 跳转:
    48                     id += gridDim.x * gridDim.y * gridDim.z * blockDim.x * blockDim.y * blockDim.z
    49 
    50             Thread 2 ━━━━━━━━
    51 
    52             ...
    53 
    54         Block 2 ━━━━━━━━━━━━━━━━
    55 
    56         ...
    57 
    58     Grid 2 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    59 
    60     ...
    61 
    62 Device ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

     ● 数组遍历测试

     1 #include <stdio.h>
     2 #include <time.h>
     3 #include "cuda_runtime.h"
     4 #include "device_launch_parameters.h"
     5 
     6 __global__ void print()
     7 {
     8     int idx = blockIdx.x * blockDim.x + threadIdx.x;
     9     int idy = blockIdx.y * blockDim.y + threadIdx.y;
    10     int idz = blockIdx.z * blockDim.z + threadIdx.z;
    11     int id  = idz * gridDim.x * blockDim.x * gridDim.y * blockDim.y + idy * gridDim.x * blockDim.x + idx;
    12     printf("gridDim %2d-%2d-%2d, block %2d-%2d-%2d, "
    13             "blockDim %2d-%2d-%2d, thread %2d-%2d-%2d, "
    14             "x=%2d,y=%2d,z=%2d,total %2d
    ",
    15         gridDim.x, gridDim.y, gridDim.z, blockIdx.x, blockIdx.y, blockIdx.z,
    16         blockDim.x, blockDim.y, blockDim.z, threadIdx.x, threadIdx.y, threadIdx.z,
    17         idx, idy, idz, id);
    18     return;
    19 }
    20 
    21 int main()
    22 {
    23     print << <dim3(2, 3, 4), dim3(2, 3, 4) >> >();
    24     cudaDeviceSynchronize();
    25 
    26     getchar();
    27     return 0;
    28 }

    ▶ P62。Fortran和Matlab采用的是是列优先的存储方式,在与C程序交互的过程中要注意转置。

    ▶ P112。访问全局内存时,若同一个Warp中所有线程都执行同一条指令来访问全局内存中的连续地址,访问效率最高。

    ▶ P116。当数据放入共享内存中,不管是以行方式还是列方式访问都不会造成性能差异。

    ▶ P120。线程块并行和线程并行的关系。线程调度为细粒度,效率高;线程块并行为粗粒度,每次调度都要重新分配资源。在采用分治法解决问题时,先将大规模的问题分解为几个小规模问题,分别用线程块实现,线程块内再将任务细化为线程并行。线程块之间粗粒度,块内细粒度,可以充分利用硬件资源,降低线程并行的计算复杂度。应尽量安排每一个线程完成较多工作,并采用更少的线程数。

    ▶ P128。浮点数相关。

    ● 负数的补码是其绝对值数按位取反再加 1。

    ● 余码的好处是无符号比较器可以用来比较有符号数,无符号比较器比较小,速度快。

    ● 单精度浮点数,1位符号位,8位阶码,23为位尾数;双精度浮点数,1为符号位,11为阶码,52位尾数。

    ● NaN 有两种。SignalingNaN 作为运算操作的输入会引发异常,中断执行,通常用于标记未初始化的数据;quietNaN 可以作为运算操作的输入,结果仍为 quietNaN,不会中断执行。

    ● 由于计算舍入造成的误差,称为 0.5D ULP (Unit in the Last Place) 误差。

    ● 串行 / 并行算法在精确性上并没有绝对优势(可以分别举出精确性串行高于并行,或并行高于串行的例子)。应根据需要决定是否接受算法和计算结果。选择算法时可以先对数据进行排序、分组,这对串行和并行程序都能提高精确性。

  • 相关阅读:
    jxl 单元格画斜线
    阿里云 tomcat 配置 注意
    java 的 数据库连接测试类 (SQL server)
    关于使用jackson.jar解析JSON时,大写JSON key值发生报错的问题
    JS配置文件动态加载CSS,js和定义请求路径
    SQL SERVER 2008升级SQL SERVER 2008 R2或者10.00.1600升级10.50.1600
    IDEA 启动运行的tomcat服务器项目,只能使用localhost访问的解决方法:
    舞会
    01序列
    交错01串
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/7653510.html
Copyright © 2011-2022 走看看