首页 > 系统相关 >《CUDA编程:基础与实践》读书笔记(5):统一内存编程

《CUDA编程:基础与实践》读书笔记(5):统一内存编程

时间:2023-08-12 11:12:50浏览次数:43  
标签:__ const 读书笔记 int double void 编程 内存 CUDA

统一内存(unified memory)是一种逻辑上的概念,它既不是显存、也不是主机内存,而是CPU和GPU都可以访问并能保证一致性的虚拟存储器。使用统一内存对硬件有较高的要求:

  • 对于所有功能,GPU架构都必须不低于Kepler架构,主机应用程序必须为64位。
  • 对于一些较新的功能,至少需要Pascal架构的GPU,且主机必须是Linux系统。

使用统一内存编程的优势如下:

  • 统一内存使编程更加简单。不需要手动将数据在主机和设备之间传输,也不需要针对同一组数据定义两个指针并分别分配主机内存和设备内存。对于某个统一内存变量,可以直接从CPU或GPU中访问。
  • 可能会提供比手工移动数据更好的性能。统一内存的底层实现,可能会自动将一部分数据放到离某个处理器更近的位置,比如部分放到显存中,部分放到主存中,从而让相关数据尽量靠近对应的处理器。虽然统一内存机制可以部分地做到这些,但很多情况下还是需要手动给编译器一些提示,这部分功能需要Linux系统且不低于Pascal架构的GPU。
  • 允许GPU在使用统一内存的情况下,进行超量分配。超出GPU内存额度的部分可能存放在主机上。该功能也要求Linux系统且不低于Pascal架构的GPU。

动态分配统一内存使用的CUDA运行时API函数如下:

cudaError_t cudaMallocManaged(void **devPtr, size_t size, unsigned int flags = cudaMemAttachGlobal);

相比于cudaMalloc函数,该函数多个一个可选参数flags,其默认值cudaMemAttachGlobal代表分配的全局内存可由任何设备通过任何CUDA流进行访问。只能在主机端使用该函数分配统一内存,不能在核函数中使用该函数。分配了统一内存的变量既可以被设备访问,也可以被主机访问。从核函数的角度看,统一内存和普通设备内存在使用上没有任何区别,性能也基本相同。使用动态统一内存改写的数组相加例程如下:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cmath>
#include <cstdio>

const double EPSILON = 1.0e-15;
const double a = 1.23;
const double b = 2.34;
const double c = 3.57;

void __global__ add(const double* x, const double* y, double* z)
{
    const int n = blockDim.x * blockIdx.x + threadIdx.x;
    z[n] = x[n] + y[n];
}

void check(const double* z, const int N)
{
    bool has_error = false;
    for (int n = 0; n < N; ++n)
    {
        if (fabs(z[n] - c) > EPSILON)
        {
            has_error = true;
        }
    }
    printf("%s\n", has_error ? "Has errors" : "No errors");
}

int main(void)
{
    const int N = 100000000;
    const int M = sizeof(double) * N;
    double* x, * y, * z;
    cudaMallocManaged((void**)&x, M);
    cudaMallocManaged((void**)&y, M);
    cudaMallocManaged((void**)&z, M);

    for (int n = 0; n < N; ++n)
    {
        x[n] = a;
        y[n] = b;
    }

    const int block_size = 128;
    const int grid_size = N / block_size;
    add << <grid_size, block_size >> > (x, y, z);

    cudaDeviceSynchronize();
    check(z, N);

    cudaFree(x);
    cudaFree(y);
    cudaFree(z);
    return 0;
}

统一内存也可以静态分配,只要在修饰符的__device__的基础上再加上修饰符__managed__即可。这样的变量是在任何函数外部定义的,可见范围是所在源文件(更准确地说是所在翻译单元)。官方文档《CUDA C++ Programming Guide》中的示例如下:

__device__ __managed__ int ret[1000];
__global__ void AplusB(int a, int b) {
    ret[threadIdx.x] = a + b + threadIdx.x;
}
int main() {
    AplusB<<< 1, 1000 >>>(10, 100);
    cudaDeviceSynchronize();
    for(int i = 0; i < 1000; i++)
        printf("%d: A+B = %d\n", i, ret[i]);
    return 0;
}

标签:__,const,读书笔记,int,double,void,编程,内存,CUDA
From: https://www.cnblogs.com/moonzzz/p/17621592.html

相关文章

  • 编程语言只是工具,不是目的
    编程语言只是工具,不是目的如果想做传统后端,学Java;如果想做游戏,用Unity学C#,用Unreal学C++;如果想做前端,学Javascript和Typescript;如果想做PaaS、SaaS,学Golang;如果想做IaaS,学C++、C;如果想去技术型创业公司,学Rust;如果想做区块链,学Golang;如果想做嵌入式开发,学C;如果想......
  • 什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux
    脚本脚本就是批处理平常一个命令不能完成的任务,写到一个文件当中,有多个命令按照一定的逻辑来进行编写编写完后去执行这个文件,随后他就会按照流程多个命令,多个语句,达到批处理的一个任务shell 系统分成了三层第一层是kernel(内核)内核是操作系统的核心,主要负责1管理硬件,电脑cpu是什么......
  • Javascript 面向对象编程
    avascript是一个类C的语言,他的面向对象的东西相对于C++/Java比较奇怪,但是其的确相当的强大,在 Todd同学的“对象的消息模型”一文中我们已经可以看到一些端倪了。这两天有个前同事总在问我Javascript面向对象的东西,所以,索性写篇文章让他看去吧,这里这篇文章主要想从一个整体的角度......
  • golang网络编程
    1简介Go语言的网络编程主要使用net包来实现。该包提供了一组基本的网络功能,包括TCP和UDP套接字、IP地址和端口号的处理、以及一些高级特性,如非阻塞I/O和HTTP客户端库。本文简单介绍一下如何使用net包进行TCP通信2TCP通信TCP服务端处理流程:监听端口接收......
  • 拓端tecdat|用R语言编程代写制作交互式图表和地图
    用R语言制作交互式图表和地图可以直接从R/RStudio制作在线交互式图表和地图。 配置启动RStudio,创建一个新的RScript,然后将工作目录设置为下载的数据文件夹。 使ggplot2图表成为交互式Plotly图表制作交互式点线图以下代码将安装并加载程序包(该程序还将......
  • 拓端tecdat|使用GIS编程代写制作静态地图和处理地理数据
    使用GIS制作静态地图和处理地理数据QGIS简介GQIS是领先的免费开放源地理信息系统(GIS)应用程序。它能够进行复杂的地理数据处理和分析,还可以用于设计发布质量的数据驱动地图。 启动QGIS,应该看到类似以下的屏幕:  如果您的屏幕看起来与众不同,请View>Panels......
  • 绝了!学编程的还有不知道的吗?这个Java开发工具免费了!
    智能开发正在迅速走红!随着ChatGPT的广泛应用,智能开发越来越受到关注。然而,实际上,在数年前开始尝试智能开发的探索。自从2014年ForresterResearch提出"低代码"的概念以来,低代码平台的发展非常迅速。除了OutSystems和Mendix等低代码厂商之外,微软、谷歌等大型公司也纷纷开始着手低代......
  • 大模型时代的程序员:不会用AIGC编程,未来5年将被淘汰?
    作者|郭炜策划|凌敏前言下面是一段利用Co-Pilot辅助开发的小视频,这是ApacheSeaTunnel开发者日常开发流程中的一小部分。如果你还没有用过Co-Pilot、ChatGPT或者私有化大模型帮助你辅助开发的话,未来的5年,你可能很快就要被行业所淘汰。因为这些善于使用AIGC辅助编......
  • 8.11-下午-电极02-03eg(线切割)编程雕不了用电极 电极做不出来的 用线切割
      ......
  • Shell编程规范与变量二
    目录1.条件测试1.1文件测试1.2数字测试1.3字符串测试1.4逻辑测试1.5双中括号1.6(){}1.7if语句1.7.1单分支1.7.2双分支1.7.3多分支1.8case命令1.9echo命令2.使用shell脚本编译安装nginx1.条件测试条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达......