cuda编程学习笔记 第二章 cuda memory management

2023-11-10

应用的性能可能有 75% 都花费在内存相关问题上。

NVPROF and NVVP

这俩是调试工具,不知道是不是基于CUPTI (CUDA Profiler Tools Interface)。

NVPROF是命令行工具,nvvp是可视化工具。

nvvp有四个模块:Timeline,Summary,Guide,Analysis results
其中 Guide 适合新手,新手应该多注意。

为了分析出应用的性能瓶颈,我们需要timeling analysis 和 metric analysis

编译:
要include cuda_profiler_api.h 和 helper_functions.h
命令1
nvcc -I"D:/cuda/NVIDIA Corporation_v10.1/common/inc" -gencode arch=compute_61,code=sm_61 -Xcompiler /wd4819 -o sgemm sgemm.cu
命令2 创建 nvvp文件
nvprof -o sgemm.nvvp .\sgemm.exe
13388 NVPROF is profiling process 13388, command: .\sgemm.exe
Operation Time= 0.0046 msec
13388 Generated result file: D:\codes\Learn-CUDA-Programming-master\Learn-CUDA-Programming-master\Chapter02\02_memory_overview\01_sgemm\sgemm.nvvp

运行nvvp,打开 sgemm.nvvp文件

Global memory / device memory

global memory 是从host复制过去的默认空间
cudaMalloc 和 cudaFree cudaMemcpy

coalesced memory access / uncoalesced memory access

warp:32threads running in SMs。
例如 一个SM运行两个block,每个block128线程,则一共 8 个 warp。这些 warp 公用一个SM的shared memory。
每个warp中的线程以SIMT模式运行,也就是所有线程同时运行同一个命令

warp下的内存访问需要coalesced memory access,squential memory access is adjacent.

总而言之尽量连续访问、数据aligned

texture memory

一般用来存储大部分线程都要访问的少量数据,比如参数之类。同一个warp的线程访问同一个地址会导致所有线程在每个时钟周期请求数据,但是在texture memory上有优化。2D访问、3D访问也有优化,总之就是读的快、不能写。

shared memory

shared memory以banks的形式排列,要防止同一个warp里的线程同时访问同一个bank,至于不同warp之间的不太清楚。

registers

local variables are stored in registers
尽量别弄太多本地变量,寄存器和thread有关

pinned memory

尽量不在host 和 device之间传输数据
用pinned memory
把许多小数据传输合并成一个大batch
用计算来掩盖传输

传输数据时默认先创建一个pinned memory,然后将一个个page复制过去,再从pinned memory里将数据复制到device(通过DMA)。通过cudaMallocHost可以之间分配一个pinned memory。

Unified memory

给GPU和CPU提供一个统一的地址
cudaMallocManaged分配空间,不是立刻分配,下一次host第一个访问该空间就分配host,否则device。(first touch)

当device需要访问某个page,但是page正在host映射的空间里,这时会让host取消映射,transfer这个page到device的物理空间,device再映射这个page。

warp per page 技术,每个warp负责64K,一个page:

__global__ void init(int n, float *x, float *y) {
    int lane_id = threadIdx.x & 31;//本线程是该warp的第几个线程
    size_t warp_id = (threadIdx.x + blockIdx.x * blockDim.x) >> 5;//blockDim.x是一个block的线程数
    size_t warps_per_grid = (blockDim.x * gridDim.x) >> 5;//
    size_t warp_total = ((sizeof(float)*n) + STRIDE_64K-1) / STRIDE_64K;//pages

    // if(blockIdx.x==0 && threadIdx.x==0) {
    //     printf("\n TId[%d] ", threadIdx.x);
    //     printf(" WId[%u] ", warp_id);
    //     printf(" LId[%u] ", lane_id);
    //     printf(" WperG[%u] ", warps_per_grid);
    //     printf(" wTot[%u] ", warp_total);
    //     printf(" rep[%d] ", STRIDE_64K/sizeof(float)/32);
    // }

    for( ; warp_id < warp_total; warp_id += warps_per_grid) {
        #pragma unroll//告诉编译器任意展开并行等都是安全的
        for(int rep = 0; rep < STRIDE_64K/sizeof(float)/32; rep++) {
            size_t ind = warp_id * STRIDE_64K/sizeof(float) + rep * 32 + lane_id;
            if (ind < n) {
              x[ind] = 1.0f;
              // if(blockIdx.x==0 && threadIdx.x==0) {
              // 	printf(" \nind[%d] ", ind);
              // } 
              y[ind] = 2.0f;
            }
        }
    }
}

data prefetching: cudaMemPerfetchAsync()
预先告诉程序下一个设备是谁。这个最快。

cudaMemAdvice()系列API:
SetReadMostly、PreferredLocation、SetAccessBy等。

UM技术把device和host的内存看作同一个内存,可以用来解决很多GPU内存不够的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cuda编程学习笔记 第二章 cuda memory management 的相关文章

  • Yocto for Nvidia Jetson 由于 GCC 7 而失败 - 无法计算目标文件的后缀

    我正在尝试将 Yocto 与 meta tegra 一起使用 https github com madisongh meta tegra https github com madisongh meta tegra 为 Nvidia Jets
  • 加速Cuda程序

    要更改哪一部分来加速此代码 代码到底在做什么 global void mat Matrix a Matrix b int tempData new int 2 tempData 0 threadIdx x tempData 1 blockI
  • cuda中有模板化的数学函数吗? [复制]

    这个问题在这里已经有答案了 我一直在寻找 cuda 中的模板化数学函数 但似乎找不到 在普通的 C 中 如果我调用std sqrt它是模板化的 并且将根据参数是浮点数还是双精度数执行不同的版本 我想要这样的 CUDA 设备代码 我的内核将真
  • TensorRT 多线程

    我正在尝试使用 python API 来使用 TensorRt 我试图在多个线程中使用它 其中 Cuda 上下文与所有线程一起使用 在单个线程中一切正常 我使用 docker 和 tensorrt 20 06 py3 图像 onnx 模型和
  • 有没有一种有效的方法来优化我的序列化代码?

    这个问题缺乏细节 因此 我决定创建另一个问题而不是编辑这个问题 新问题在这里 我可以并行化我的代码吗 还是不值得 https stackoverflow com questions 17937438 can i parallelize my
  • __device__ __constant__ 常量

    有什么区别吗 在 CUDA 程序中定义设备常量的最佳方法是什么 在 C 主机 设备程序中 如果我想将常量定义在设备常量内存中 我可以这样做 device constant float a 5 constant float a 5 问题 1
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 内联 PTX 汇编代码强大吗?

    我看到一些代码示例 人们在 C 代码中使用内联 PTX 汇编代码 CUDA工具包中的文档提到PTX很强大 为什么会这样呢 如果我们在 C 代码中使用这样的代码 我们会得到什么好处 内联 PTX 使您可以访问未通过 CUDA 内在函数公开的指
  • 最小化 MC 模拟期间存储的 cuRAND 状态数量

    我目前正在 CUDA 中编写蒙特卡罗模拟 因此 我需要生成lots使用随机数cuRAND图书馆 每个线程处理一个巨大的元素floatarray 示例中省略 并在每次内核调用时生成 1 或 2 个随机数 通常的方法 参见下面的示例 似乎是为每
  • “gld/st_throughput”和“dram_read/write_throughput”指标之间有什么区别?

    在 CUDA 可视化分析器版本 5 中 我知道 gld st requested throughput 是应用程序请求的内存吞吐量 然而 当我试图找到硬件的实际吞吐量时 我很困惑 因为有两对似乎合格的指标 它们是 gld st throug
  • OS X 10.8 上的 PyCuda / 多处理问题

    我正在开发一个项目 将计算任务分配给多个 python 进程 每个进程都与其自己的 CUDA 设备关联 生成子进程时 我使用以下代码 import pycuda driver as cuda class ComputeServer obje
  • 大型跨平台软件项目的技巧/资源

    我将开始一个大型软件项目 涉及跨平台 GUI 和大量的数字运算 我计划用 C 和 CUDA 编写大部分应用程序后端 并用 Qt4 编写 GUI 我计划使用 Make 作为我的构建系统 这将是一个只有两名开发人员的项目 一旦我相对深入地了解它
  • CUDA:获取数组中的最大值及其索引

    我有几个块 每个块在整数数组的单独部分上执行 举个例子 块一从 array 0 到 array 9 块二从 array 10 到 array 20 我可以获得每个块的数组最大值的索引的最佳方法是什么 示例块一 a 0 到 a 10 具有以下
  • CUDA 5.0错误LNK2001:cuda方法无法解析的外部符号

    我的链接器有错误 1 gt ManifestResourceCompile 1 gt All outputs are up to date 1 gt kernel cu obj error LNK2001 unresolved extern
  • CUDA Thrust 的多 GPU 使用

    我想使用我的两张显卡通过 CUDA Thrust 进行计算 我有两张显卡 在单卡上运行对于两张卡都适用 即使我在 std vector 中存储两个 device vector 也是如此 如果我同时使用两张卡 循环中的第一个周期将起作用并且不
  • CUDA计算能力2.0。全局内存访问模式

    CUDA 计算能力 2 0 Fermi 全局内存访问通过 768 KB L2 缓存进行 看起来 开发人员不再关心全局内存库 但全局内存仍然非常慢 因此正确的访问模式很重要 现在的重点是尽可能多地使用 重用 L2 我的问题是 如何 我将感谢一
  • OpenCV 2.4.3rc 和 CUDA 4.2:“OpenCV 错误:没有 GPU 支持”

    我在这张专辑中上传了几张截图 https i stack imgur com TELST jpg https i stack imgur com TELST jpg 我正在尝试在 Visual Studio 2008 中的 OpenCV 中
  • CUDA 添加矩阵的行

    我试图将 4800x9600 矩阵的行加在一起 得到一个 1x9600 的矩阵 我所做的是将 4800x9600 分成 9 600 个矩阵 每个矩阵长度为 4800 然后我对 4800 个元素进行缩减 问题是 这真的很慢 有人有什么建议吗
  • 将 cuda 数组传递给 Thrust::inclusive_scan

    我可以对 cpu 上的数组使用包容性扫描 但是否可以对 gpu 上的数组执行此操作 注释是我知道有效但我不需要的方式 或者 是否有其他简单的方法可以对设备内存中的数组执行包含扫描 Code include
  • goto 指令对 CUDA 代码中扭曲内发散的影响

    对于CUDA中简单的warp内线程发散 我所知道的是SM选择一个重新收敛点 PC地址 并在两个 多个路径中执行指令 同时禁用未采用该路径的线程的执行效果 例如 在下面的代码中 if threadIdx x lt 16 A do someth

随机推荐