CUDA 共享内存 shared memory

共享内存作用

  • 共享内存在片上(on-chip),与本地内存和全局内存相比具有更高的带宽和更低的延迟;
  • **共享内存中的数据在线程块内所有线程可见,**可用线程间通信,共享内存的生命周期也与所属线程块一致;
  • 使用__shared__修饰的变量存放于共享内存中
  • 共享内存可定义动态与静态两种;
  • 每个SM的共享内存数量是一定的,也就是说,如果在单个线程块中分配过度的共享内存,将会限制活跃线程束的数量;
  • 访问共享内存必须加入同步机制:线程块内同步 void_syncthreads();
  • 不同计算能力的架构,每个SM中拥有的共享内存大小是不同的
  • 每个线程块使用共享内存的最大数量不同架构是不同的
  • 此功能(与线程同步结合)有许多用途,例如用户管理的数据缓存、高性能协作并行算法(例如并行缩减),以及在原本不可能的情况下促进全局内存合并。

静态共享内存

定义在核函数中,定义时确定大小。

示例:CUDAExample: 点积运算 Dot Product-CSDN博客

动态共享内存

在声明的时候没有指定数组的大小

静态和动态共享内存的示例:实现数组的逆向交给交互

cpp 复制代码
#include <stdio.h>
#include "cpu_anim.h"
#include "cuda_runtime.h"
#include <device_launch_parameters.h>
#include <device_functions.h>

// 静态共享内存
__global__ void staticReverse(int* d, int n)
{
    __shared__ int s[64];
    int t = threadIdx.x;
    int tr = n - t - 1;
    s[t] = d[t];
    __syncthreads();
    d[t] = s[tr];
}

// 动态共享内存的第一种调用方法
__global__ void dynamicReverse(int* d, int n)
{
    extern __shared__ int s[];
    int t = threadIdx.x;
    int tr = n - t - 1;
    s[t] = d[t];
    __syncthreads();
    d[t] = s[tr];
}

// 动态共享内存的第一种调用方法
extern __shared__ int d_s[];   // 固定格式
__global__ void dynamicReverseEx(int* d, int n)
{
    int t = threadIdx.x;
    int tr = n - t - 1;
    d_s[t] = d[t];
    __syncthreads();
    d[t] = d_s[tr];
}

int main(void)
{
    const int n = 64;
    int a[n], r[n], d[n];

    for (int i = 0; i < n; i++) {
        a[i] = i;
        r[i] = n - i - 1;
        d[i] = 0;
    }

    int* d_d;
    cudaMalloc(&d_d, n * sizeof(int));

    // run version with static shared memory
    cudaMemcpy(d_d, a, n * sizeof(int), cudaMemcpyHostToDevice);
    staticReverse << <1, n >> > (d_d, n);
    cudaMemcpy(d, d_d, n * sizeof(int), cudaMemcpyDeviceToHost);
    for (int i = 0; i < n; i++)
        if (d[i] != r[i]) printf("Error: d[%d]!=r[%d] (%d, %d)\n", i, i, d[i], r[i]);

    // run dynamic shared memory version
    cudaMemcpy(d_d, a, n * sizeof(int), cudaMemcpyHostToDevice);
    // 第三个参数指定的是共享内存的大小
    dynamicReverse << <1, n, n * sizeof(int) >> > (d_d, n);
    cudaMemcpy(d, d_d, n * sizeof(int), cudaMemcpyDeviceToHost);
    for (int i = 0; i < n; i++)
        if (d[i] != r[i]) printf("Error: d[%d]!=r[%d] (%d, %d)\n", i, i, d[i], r[i]);

    // run dynamic shared memory version 
    cudaMemcpy(d_d, a, n * sizeof(int), cudaMemcpyHostToDevice);
    // 第三个参数指定的是共享内存的大小
    dynamicReverseEx << <1, n, n * sizeof(int) >> > (d_d, n);
    cudaMemcpy(d, d_d, n * sizeof(int), cudaMemcpyDeviceToHost);
    for (int i = 0; i < n; i++)
        if (d[i] != r[i]) printf("Error: d[%d]!=r[%d] (%d, %d)\n", i, i, d[i], r[i]);

    return 0;
}
相关推荐
闻道且行之13 小时前
Windows|CUDA和cuDNN下载和安装,默认安装在C盘和不安装在C盘的两种方法
windows·深度学习·cuda·cudnn
seasonsyy17 小时前
2.安装CUDA详细步骤(含安装截图)
python·深度学习·环境配置·cuda
点云SLAM3 天前
Pytorch中cuda相关操作详见和代码示例
人工智能·pytorch·python·深度学习·3d·cuda·多gpu训练
mpr0xy3 天前
编译支持cuda硬件加速的ffmpeg
ai·ffmpeg·nvidia·cuda
ouliten7 天前
cuda编程笔记(9)--使用 Shared Memory 实现 tiled GEMM
笔记·cuda
ZhiqianXia10 天前
片上网络(NoC)拓扑结构比较
cuda
木子杳衫19 天前
显卡 | CUDA
显卡·cuda
William.csj22 天前
Pytorch/CUDA——flash-attn 库编译的 gcc 版本问题
pytorch·cuda
野蛮人6号24 天前
如何查看自己电脑的CUDA版本?
cuda
SHIPKING3931 个月前
【CUDA&cuDNN安装】深度学习基础环境搭建
人工智能·深度学习·cuda·cudnn