【CUDA学习笔记】OneFlow公众号CUDA算子优化文章学习笔记

1 CUDA学习资料合集

【OneFlow】岁末年初,为你打包了一份技术合订本

2 GPU概念介绍

《GPU的硬件结构与执行原理 —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

2.1 内存模型

2.1.1 Bank介绍

《GPU硬件结构之bank —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化》

3 算子优化

3.1 Conv

3.1.1 Img2col:卷积优化算法

博文《基于OneFlow实现Unfold、Fold算子》(以下简称为“《Fold优化》”)
《基于OneFlow实现Unfold、Fold算子》:理解img2col

3.1.2 Unfold & Fold

《基于OneFlow实现Unfold、Fold算子》:Unfold、Fold算子是卷积优化的基础操作

为什么这里out在索引时设计成6维的方式来进行操作呢?

在阅读《Fold优化》时,我们发现out采用6维的形式来进行操作,
在这里插入图片描述
这样是为了CUDA编程时,索引可以直接对应上去,这样代码写作起来会更加简单;

3.2 Norm

3.2.2 LayerNorm

《CUDA优化之LayerNorm性能优化实践》

3.3 Elementwise operator

《高效、易用、可拓展我全都要:OneFlow CUDA Elementwise模板库的设计优化思路》

3.4 Softmax

《如何实现一个高效的 Softmax CUDA kernel?——OneFlow 性能优化分享》

(1)OneFlow为什么在Softmax实现时会使用ReduceMax操作呢?

这个问题的来源是这样的,博文《如何实现一个高效的 Softmax CUDA kernel?——OneFlow 性能优化分享》(以下简称为“《Softmax优化》”)在描述Softmax的CUDA实现时表示使用了ReduceMax操作,(也就是求某个维度上的最大值),但是根据Softmax的公式,这个操作在数学上其实是没有必要的,那为什么OneFlow会在CUDA实现时使用ReduceMax操作呢?
关于这一点,我们请教了晓雨哥,

【晓雨哥】:
应该是防溢出吧。

于是我们可以知道,先进行ReduceMax操作的目的是为了减去最大值,从而减小每个元素的绝对值,防止指数操作可能产生的数值溢出。

3.5 Dim transformation

《如何实现比PyTorch快6倍的Permute/Transpose算子?》

4 性能优化方法

4.1 CUDA Kernel中 grid_size 和 block_size 的设置优化

《如何设置CUDA Kernel中的grid_size和block_size?》

4.2 访存优化

《OneFlow GPU性能优化方法一:减少全局内存的访问 —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

4.2.1 Kernel fusion:核函数融合,一次访存,多次计算

(1)Element-wise kernel fusion

《1. Element-wise kernel fusion —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

(2)借助 shared memory 合并带有Reduce计算的Kernel

《2. 借助shared memory合并带有Reduce计算的Kernel —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

(3)使用bitset优化mask计算

《3. 减少实际需要的访存大小(以ReLU为例) —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

4.1.1 Memory access merging:内存访问合并

《OneFlow GPU性能优化方法二:确保全局内存访问合并 —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

以 bitset mask 生成为例讲解访存合并

《如何生成这个 bitset mask 加速Kernel的访存 —— 开源100天,OneFlow送上“百天大礼包”:深度学习框架如何进行性能优化 》

4.2 计算优化

《OneFlow GPU性能优化方法三:优化Kernel计算量 》

4.3 延迟隐藏

《OneFlow GPU性能优化方法四:延迟隐藏 》

4.4 优化小技巧

《OneFlow 其他GPU性能优化小技巧 》

5 CUDA高性能计算经典优化问题

① 归约

《CUDA高性能计算经典问题①:归约》

② 前缀和

《CUDA高性能计算经典问题②:前缀和》

③ 矩阵乘法

《关于ChatGPT的一切;CUDA入门之矩阵乘;PyTorch 2.0发布|AI系统前沿动态》

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用CUDA C编写卷积操作的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <cuda_runtime.h> #define BLOCK_SIZE 16 __global__ void convolve(float *input, float *output, float *kernel, int input_width, int input_height, int kernel_size) { int row = blockIdx.y * blockDim.y + threadIdx.y; int col = blockIdx.x * blockDim.x + threadIdx.x; float sum = 0.0f; for (int i = 0; i < kernel_size; ++i) { for (int j = 0; j < kernel_size; ++j) { int input_row = row + i - kernel_size / 2; int input_col = col + j - kernel_size / 2; if (input_row >= 0 && input_row < input_height && input_col >= 0 && input_col < input_width) { sum += input[input_row * input_width + input_col] * kernel[i * kernel_size + j]; } } } output[row * input_width + col] = sum; } int main() { int input_width = 512; int input_height = 512; int kernel_size = 5; float *input = (float*)malloc(input_width * input_height * sizeof(float)); for (int i = 0; i < input_width * input_height; ++i) { input[i] = rand() % 256 / 255.0f; } float *kernel = (float*)malloc(kernel_size * kernel_size * sizeof(float)); for (int i = 0; i < kernel_size * kernel_size; ++i) { kernel[i] = rand() % 256 / 255.0f; } float *output = (float*)malloc(input_width * input_height * sizeof(float)); float *d_input, *d_kernel, *d_output; cudaMalloc(&d_input, input_width * input_height * sizeof(float)); cudaMalloc(&d_kernel, kernel_size * kernel_size * sizeof(float)); cudaMalloc(&d_output, input_width * input_height * sizeof(float)); cudaMemcpy(d_input, input, input_width * input_height * sizeof(float), cudaMemcpyHostToDevice); cudaMemcpy(d_kernel, kernel, kernel_size * kernel_size * sizeof(float), cudaMemcpyHostToDevice); dim3 block_size(BLOCK_SIZE, BLOCK_SIZE); dim3 grid_size((input_width + BLOCK_SIZE - 1) / BLOCK_SIZE, (input_height + BLOCK_SIZE - 1) / BLOCK_SIZE); convolve<<<grid_size, block_size>>>(d_input, d_output, d_kernel, input_width, input_height, kernel_size); cudaMemcpy(output, d_output, input_width * input_height * sizeof(float), cudaMemcpyDeviceToHost); cudaFree(d_input); cudaFree(d_kernel); cudaFree(d_output); free(input); free(kernel); free(output); return 0; } ``` 该示例代码中,`convolve()`函数是卷积操作的核函数,它接收输入图像、输出图像和卷积核作为输入参数,以及输入图像尺寸和卷积核尺寸。在核函数中,每个线程负责计算输出图像中的一个像素值,它将卷积核与输入图像中对应像素的值相乘,并将结果累加到一个变量中。最后,输出图像中对应像素的值被赋为累加的结果。 在主函数中,我们首先生成随机的输入图像和卷积核,然后在GPU上分配内存,将输入图像和卷积核从主机内存复制到设备内存中,调用卷积核函数进行卷积操作,最后将输出图像从设备内存复制到主机内存中,并释放分配的内存。 在实际使用中,您需要根据自己的需求修改输入图像、卷积核和卷积核函数,以适应不同的场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值