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;
}
相关推荐
李昊哲小课1 小时前
WSL Ubuntu 24.04 GPU 加速环境完整安装指南
c++·pytorch·深度学习·ubuntu·cuda·tensorflow2
bloglin999991 天前
Ubuntu22.04 离线安装 CUDA12.3 依赖报错解决方案
ai·cuda
fpcc6 天前
并行编程实战——CUDA编程的图之六子图的创建
人工智能·cuda
明月醉窗台7 天前
[jetson] AGX Xavier 安装Ubuntu18.04及jetpack4.5
人工智能·算法·nvidia·cuda·jetson
飞翔的SA7 天前
全程 Python:无需离开 Python 即可实现光速级 CUDA 加速,无需c++支持
开发语言·c++·python·nvidia·cuda
阿钱真强道12 天前
01 飞腾 S5000C 服务器环境搭建实战:PyTorch + CUDA + RTX 4090D 安装与验证
pytorch·cuda·aarch64·深度学习环境搭建·飞腾服务器·s5000c·rtx4090d
酌量15 天前
nvidia orin agx刷机忘记CUDA runtime,安装torch和cuda
linux·笔记·ubuntu·torch·cuda·agx
明月醉窗台16 天前
[Jetson] NVIDIA Jetson 全系列边缘计算芯片进阶指南
人工智能·边缘计算·cuda·jetson
明月醉窗台20 天前
[Jetson] 在Jetson Xavier AGX编译opencv+cuda
人工智能·opencv·计算机视觉·cuda·jetson
专注VB编程开发20年21 天前
CUDA实现随机切割算法,显卡多线程计算
算法·cuda