🍪
cookielau
  • Introduction
  • Machine Learning
    • Distributed
      • Bookmarks
    • NLP
      • Transformers
    • MLC
      • Tensor Program Abstraction
      • End-to-End Module Execution
  • Framework
    • PyTorch
      • Bookmarks
      • Model
      • Shared
      • Miscellaneous
    • Tensorflow
      • Bookmarks
      • Model
      • Shared
      • Miscellaneous
    • CUDA
      • Bookmarks
    • DeepSpeed
    • Bagua
      • Model
      • Optimizer
    • Others
      • Bookmarks
  • About Me
    • 2022-04-28
  • Random Thoughts
  • Archives
    • CPP
      • Bookmarks
      • Container
      • Algorithm
      • FILE CONTROL
      • Virtual Table
      • Assembly
      • Key Words
      • Problems
      • Others
    • JAVA
      • String Container
      • Maps
    • PYTHON
      • Bookmarks
      • Python Tools
        • Batch Rename
        • Combine Excel
        • Excel Oprations
        • Read Write Excel
        • Rotate PDF
      • Library
        • Pandas Notes
        • Numpy Notes
        • Json Notes
      • Spider
        • Selenium Install
        • Selenium Locating
        • Selenium Errors
        • Selenium Basics
      • Django
        • Start Up
      • Others
    • LINUX
      • Installation
      • Cli Tools
      • WSL
      • Bugs
    • JUNIOR2
      • Economics
        • Chapter 0x01 经济管理概述
        • Chapter 0x02 微观市场机制分析
        • Chapter 0x03 生产决策与市场结构
        • Chapter 0x04 宏观经济市场分析
        • Chapter 0x05 管理的职能
        • Chapter 0x06 生产系统结构与战略
        • Chapter 0x0b 投资项目经济评价
        • Chapter 0x0f 投资项目经济评价
      • Computer Network
        • 概述
        • 分层模型
        • 物理层
        • 数据链路层
        • 网络层
        • 传输层
        • 应用层
        • HTTP(s)实验
        • [Practice]
      • Software Engineering
        • Introduction
        • Demand Analysis
        • Task Estimation
        • Presentation
      • Network Security
        • Chapter 0x01 概述
        • Chapter 0x02 密码学
        • Chapter 0x03 公钥体制
        • Chapter 0x04 消息认证
        • Chapter 0x05 密钥管理
        • Chapter 0x06 访问控制
        • Assignments
      • x86 Programming
        • Basic Knowledge
        • Program Design
        • System Interruption
        • Frequently used functions
    • MD&LaTex
      • Markdown
      • LaTex
    • NPM
      • NPM LINK
    • MyBlogs
      • 2020BUAA软工——“停下来,回头看”
      • 2020BUAA软工——“初窥构建之法”
      • 2020BUAA软工——“上手软件工程,PSP初体验!”
      • 2020BUAA软工——“深度评测官”
      • 2020BUAA软工——“并肩作战,平面交点Pro”
    • SC
      • PAC 2022
        • Lectures
      • OpenMP & MPI
        • MPI Overview
        • Message Passing Programming
        • OpenMP Overview
        • Work Sharing Directives
        • Annual Challenge
        • Future Topics in OpenMP
        • Tasks
        • OpenMP & MPI
    • Hardware
      • Nvidia GPU
        • Frequent Error
        • Memory Classification
        • CUDA_7_Streams_Simplify_Concurrency
        • Optimize_Data_Transfers_in_CUDA
        • Overlap_Data_Transfers_in_CUDA
        • Write_Flexible_Kernels_with_Grid-Stride_Loops
        • How_to_Access_Global_Memory_Efficiently
        • Using_Shared_Memory
      • Intel CPU
        • Construction
        • Optimization
        • Compilation
        • OpenMP
    • English
      • Vocab
      • Composition
    • Interview
      • Computer Network
Powered by GitBook
On this page

Was this helpful?

  1. Archives
  2. Hardware
  3. Nvidia GPU

Write_Flexible_Kernels_with_Grid-Stride_Loops

PreviousOverlap_Data_Transfers_in_CUDANextHow_to_Access_Global_Memory_Efficiently

Last updated 5 years ago

Was this helpful?

Write Flexible Kernels with Grid-Stride Loops

2020 Jan 28th CookieLau

Source:

举一个向量运算的简单例子 :

void saxpy(int n, float a, float *x, float *y)
{
    for (int i = 0; i < n; ++i)
        y[i] = a * x[i] + y[i];
}

通常的 cuda 加速就是分配足够多的线程,然后合法的线程去执行其核心代码:

__global__
void saxpy(int n, float a, float *x, float *y)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < n) 
        y[i] = a * x[i] + y[i];
}

我们通常称这种 cuda 加速的方法叫做 monolithic kernel,因为其需要创建的线程会随着需要运算的数据量的增大而增大,比如下面如果我的向量长度是 1M,则需要创建 1M 个线程:

// Perform SAXPY on 1M elements
saxpy<<<4096,256>>>(1<<20, 2.0, x, y);

显然很不美观~

这里我们推荐另一种方法: grid-stride loop 即以 grid 的大小为布长的小循环运算:

__global__
void saxpy(int n, float a, float *x, float *y)
{
    for (int i = blockIdx.x * blockDim.x + threadIdx.x; // 也是从自身thread_id开始
         i < n; 
         i += blockDim.x * gridDim.x) 
         // 不过每一个线程不止负责自己,还负责每个 grid 的自己位置上的线程
      {
          y[i] = a * x[i] + y[i];
      }
}

举个例子,如果一个 grid 中有 100 个线程,则 thread_id=0 的线程会负责 0,100,200,etc

我们看到 monolithic 中的例子不过是将 grid-Stride 中的循环展开而已,所以时间复杂度两者来说应该是相近的,测试结果也确实相近:

向量相加,大小 1<<25

Device ID: 0    Number of SMs: 80
numberOfBlocks: 32*numberOfSMs
threadsPerBlock: 256
grid-Stride time cost:525.279999 <<< numberOfBlocks, threadsPerBlocks >>>
monolithic time cost:502.784014 <<< 1<<17, 256 >>>

虽然 monolithic 快一点点,但是 grid-Stride 可以带来其他的好处如下: 1. Scalability and thread reuse: 在上面的例子也可以看出来,monolithic 在调用核函数的时候启动的 gridSize 和 blockSize 的大小是硬编码的,如果后续数据量发生了变化则需要修改硬编码,而 grid-Stride 则是只由 numberOfSMs 决定,不会由数据量的大小发生改变,更加的 Scalable。此外,monolithic 的方式要一次性分配所有的线程,那么如果极端情况下,gridSize*blockSize 无法一次性分配那么多,超过了 GPU 的能力,则无法执行核函数。 2. 对 grid-Stride 的调参也非常简便,只需要调节 numberOfBlock 一个参数即可。 3. grid-Stride 实现了对 thread 的重用(reuse),节省了单个线程的创建和销毁的时间开销还有其他的自定义的在每个线程的前后的动作(可有可无,如 thread-private and shared data initialization)。 4. Debugging 友好: 在 grid-Stride 方式下,只需要将核函数调用参数改成 <<>> 就可以实现 serial processing,通过串行来调试bug。 5. Portability and Readability: 大概就是更符合原来的 sequential 的感觉,给其他用户更方便阅读。

https://devblogs.nvidia.com/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
SAXPY