《CUDA编程:基础与实践》读书笔记(5):统一内存编程
统一内存(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;
}
《CUDA编程:基础与实践》读书笔记(5):统一内存编程的更多相关文章
- 《Essential C++》读书笔记 之 基于对象编程风格
<Essential C++>读书笔记 之 基于对象编程风格 2014-07-13 4.1 如何实现一个class 4.2 什么是Constructors(构造函数)和Destructor ...
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...
- 《编写可维护的javascript》读书笔记(中)——编程实践
上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...
- 《jQuery基础教程》读书笔记
最近在看<jQuery基础教程>这本书,做了点读书笔记以备回顾,不定期更新. 第一章第二章比较基础,就此略过了... 第三章 事件 jQuery中$(document).ready()与j ...
- 《Java并发编程的艺术》读书笔记:一、并发编程的目的与挑战
发现自己有很多读书笔记了,但是一直都是自己闷头背,没有输出,突然想起还有博客圆这么个好平台给我留着位置,可不能荒废了. 此文读的书是<Jvava并发编程的艺术>,方腾飞等著,非常经典的一本 ...
- 【读书笔记】C#高级编程 第十三章 异步编程
(一)异步编程的重要性 使用异步编程,方法调用是在后台运行(通常在线程或任务的帮助下),并不会阻塞调用线程.有3中不同的异步编程模式:异步模式.基于事件的异步模式和新增加的基于任务的异步模式(TAP, ...
- 【读书笔记】iOS-GCD-多线程编程
一,现在一个物理的CPU芯片实际上有64个(64核)CPU,如果1个CPU核虚拟为两个CPU核工作,那么一台计算机上使用多个CPU核就是理所当然的事了.尽管如此,“1个CPU核执行的CPU命令为一条无 ...
- 《深入java虚拟机》读书笔记之Java内存区域
前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,主要是方便之后进行复习. 运行时数据区域 Java虚拟 ...
- 《深入分析Java Web技术内幕》读书笔记之JVM内存管理
今天看JVM的过程中收获颇丰,但一想到这些学习心得将来可能被遗忘,便一阵恐慌,自觉得以后要开始坚持做读书笔记了. 操作系统层面的内存管理 物理内存是一切内存管理的基础,Java中使用的内存和应用程序的 ...
- Java并发编程实践读书笔记(2)多线程基础组件
同步容器 同步容器是指那些对所有的操作都进行加锁(synchronize)的容器.比如Vector.HashTable和Collections.synchronizedXXX返回系列对象: 可以看到, ...
随机推荐
- QT creator中cmake管理项目,如何引入外部库(引入Eigen库为例)
在Eigen的官网下载压缩包[点我进入] 解压到当前项目的根目录(当然你也可以自己选择目录) 在当前项目的CMakeLists.txt任意位置加入这句话include_directories(${CM ...
- TypeError: __init__() got an unexpected keyword argument 'XXXXXXXX'
解决方法:安装包的版本兼容问题,更新一下安装包的版本(如果在别的机器不报错,那就把不报错的这台机器上的安装包pip freeze > requirements.txt 下来,在报错的机器上安装一 ...
- 制作一个ai丛雨(附Python代码)
绫,再一次,再一次创造一个有你的世界 开一个随笔记录一下我的第一版ai老婆,目前只有普通对话和切换背景的功能(后面可能会加一个选人物功能) 先放一个效果图(看起来还行) 代码和注意事项都放在了下面,应 ...
- 在美国和以色列的技术支持下BP机可以爆炸,那么苹果手机是否也可以被远程引爆
要知道,这一切在技术上都是可以实现的. 由此可见,带电池的产品,最为稳妥的办法就是购买在中国组装的产品,否则其安全性是无法保证的.有人可能会说美国政府不会单独的通过这种方法去定向的杀害某个中国普通人, ...
- js 数字计算的精度问题
〇.js 的数值计算存在结果不精确的情况 最近接触财务相关系统,页面上会有一些简单的计算,就发现其实是非常简单的计算,但 js 计算出来的结果却不是预期值,可能带上一大串 0 或 9,导致计算结果错误 ...
- SqlSugarClient 代码优先建表, 根据给定的实体类,创建SQL语句, 之后创建MySQL表
using SqlSugar; using System; using System.Collections.Generic; using System.Reflection; using Syste ...
- .NET Core 线程池(ThreadPool)底层原理浅谈
简介 上文提到,创建线程在操作系统层面有4大无法避免的开销.因此复用线程明显是一个更优的策略,切降低了使用线程的门槛,提高程序员的下限. .NET Core线程池日新月异,不同版本实现都有差别,在.N ...
- Maven多模块项目 eclipse热部署 Maven项目实现 tomcat热部署
Maven 多模块项目在eclipse下面热部署,即你可以体验下无论你修改整个项目里面的任何模块的代码,都不需要用maven打包就可以看到效果, 1.首先准备好创建一个maven多项目的代码,准备好一 ...
- 【java基础】-- java接口和抽象类的异同分析
在java中,通常初学者搞不懂接口与抽象类,这也是面试比较容易问到的一个问题.下面我来谈谈自己的理解.如有不妥之处,还望批评指正,不胜感激. 目录 1.抽象类怎么定义和继承? 2.接口怎么定义和实现? ...
- 论文解读《Neural Cleanse: Identifying and Mitigating Backdoor Attacks in Neural Networks》
发表时间:2019 期刊会议:IEEE Symposium on Security and Privacy (S&P) 论文单位:UC Santa Barbara 论文作者:Bolun Wan ...