详解Pytorch显存动态分配规律探索


Posted in Python onNovember 17, 2020

下面通过实验来探索Pytorch分配显存的方式。

实验显存到主存

我使用VSCode的jupyter来进行实验,首先只导入pytorch,代码如下:

import torch

打开任务管理器查看主存与显存情况。情况分别如下:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

在显存中创建1GB的张量,赋值给a,代码如下:

a = torch.zeros([256,1024,1024],device= 'cpu')

查看主存与显存情况:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

可以看到主存与显存都变大了,而且显存不止变大了1G,多出来的内存是pytorch运行所需的一些配置变量,我们这里忽略。

再次在显存中创建一个1GB的张量,赋值给b,代码如下:

b = torch.zeros([256,1024,1024],device= 'cpu')

查看主显存情况:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

这次主存大小没变,显存变高了1GB,这是合情合理的。然后我们将b移动到主存中,代码如下:

b = b.to('cpu') 

查看主显存情况:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

发现主存是变高了1GB,显存却只变小了0.1GB,好像只是将显存张量复制到主存一样。实际上,pytorch的确是复制了一份张量到主存中,但它也对显存中这个张量的移动进行了记录。我们接着执行以下代码,再创建1GB的张量赋值给c:

c = torch.zeros([256,1024,1024],device= 'cuda')

查看主显存情况:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

发现只有显存大小变大了0.1GB,这说明,Pytorch的确记录了显存中张量的移动,只是没有立即将显存空间释放,它选择在下一次创建新变量时覆盖这个位置。接下来,我们重复执行上面这行代码:

c = torch.zeros([256,1024,1024],device= 'cuda') 

主显存情况如下:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

明明我们把张量c给覆盖了,显存内容却变大了,这是为什么呢?实际上,Pytorch在执行这句代码时,是首先找到可使用的显存位置,创建这1GB的张量,然后再赋值给c。但因为在新创建这个张量时,原本的c依然占有1GB的显存,pytorch只能先调取另外1GB显存来创建这个张量,再将这个张量赋值给c。这样一来,原本的那个c所在的显存内容就空出来了,但和前面说的一样,pytorch并不会立即释放这里的显存,而等待下一次的覆盖,所以显存大小并没有减小。

我们再创建1GB的d张量,就可以验证上面的猜想,代码如下:

d = torch.zeros([256,1024,1024],device= 'cuda') 

主显存情况如下:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

显存大小并没有变,就是因为pytorch将新的张量创建在了上一步c空出来的位置,然后再赋值给了d。另外,删除变量操作也同样不会立即释放显存:

del d

主显存情况:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

显存没有变化,同样是等待下一次的覆盖。

主存到显存

接着上面的实验,我们创建直接在主存创建1GB的张量并赋值给e,代码如下:

e = torch.zeros([256,1024,1024],device= 'cpu')

主显存情况如下:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

主存变大1GB,合情合理。然后将e移动到显存,代码如下:

e = e.to('cuda')

主显存情况如下:

详解Pytorch显存动态分配规律探索

详解Pytorch显存动态分配规律探索

主存变小1GB,显存没变是因为上面张量d被删除没有被覆盖,合情合理。说明主存的释放是立即执行的。

总结

通过上面的实验,我们了解到,pytorch不会立即释放显存中失效变量的内存,它会以覆盖的方式利用显存中的可用空间。另外,如果要重置显存中的某个规模较大的张量,最好先将它移动到主存中,或是直接删除,再创建新值,否则就需要两倍的内存来实现这个操作,就有可能出现显存不够用的情况。

实验代码汇总如下:

#%% 
import torch
#%%
a = torch.zeros([256,1024,1024],device= 'cuda') 
#%%
b = torch.zeros([256,1024,1024],device= 'cuda') 
#%%
b = b.to('cpu')
#%%
c = torch.zeros([256,1024,1024],device= 'cuda') 
#%%
c = torch.zeros([256,1024,1024],device= 'cuda') 
#%% 
d = torch.zeros([256,1024,1024],device= 'cuda') 
#%%
del d 
#%% 
e = torch.zeros([256,1024,1024],device= 'cpu') 
#%%
e = e.to('cuda')

到此这篇关于Pytorch显存动态分配规律探索的文章就介绍到这了,更多相关Pytorc显存分配规律内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python刷投票的脚本实现代码
Nov 08 Python
Python常用的内置序列结构(列表、元组、字典)学习笔记
Jul 08 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
PYQT5实现控制台显示功能的方法
Jun 25 Python
win8.1安装Python 2.7版环境图文详解
Jul 01 Python
Django Admin中增加导出CSV功能过程解析
Sep 04 Python
Python如何使用正则表达式爬取京东商品信息
Jun 01 Python
基于opencv实现简单画板功能
Aug 02 Python
python利用递归方法实现求集合的幂集
Sep 07 Python
python tkinter的消息框模块(messagebox,simpledialog)
Nov 07 Python
python调用win32接口进行截图的示例
Nov 11 Python
python 提取html文本的方法
May 20 Python
Python调用ffmpeg开源视频处理库,批量处理视频
Nov 16 #Python
python tkinter实现连连看游戏
Nov 16 #Python
详解python os.path.exists判断文件或文件夹是否存在
Nov 16 #Python
Python 删除List元素的三种方法remove、pop、del
Nov 16 #Python
python 从list中随机取值的方法
Nov 16 #Python
python实现在列表中查找某个元素的下标示例
Nov 16 #Python
python如何获得list或numpy数组中最大元素对应的索引
Nov 16 #Python
You might like
PHP中文件缓存转内存缓存的方法
2011/12/06 PHP
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
PHP保存session到memcache服务器的方法
2016/01/19 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
PHP PDOStatement::bindColumn讲解
2019/01/30 PHP
javascript 树控件 比较好用
2009/06/11 Javascript
Three.js源码阅读笔记(物体是如何组织的)
2012/12/27 Javascript
jQuery 三击事件实现代码
2013/09/11 Javascript
JavaScript数据结构和算法之图和图算法
2015/02/11 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
jquery.cookie.js用法实例详解
2015/12/25 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
2016/10/10 Javascript
javascript中json对象json数组json字符串互转及取值方法
2017/04/19 Javascript
JQuery 获取Dom元素的实例讲解
2017/07/08 jQuery
jQuery实现html table行Tr的复制、删除、计算功能
2017/07/10 jQuery
基于vue.js快速搭建图书管理平台
2017/10/29 Javascript
最实用的JS数组函数整理
2017/12/05 Javascript
基于JavaScript中标识符的命名规则介绍
2018/01/06 Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
2018/06/22 Javascript
jQuery实现点击旋转,再点击恢复初始状态动画效果示例
2018/12/11 jQuery
Vuerouter的beforeEach与afterEach钩子函数的区别
2018/12/26 Javascript
在Python的Django框架中simple-todo工具的简单使用
2015/05/30 Python
开源软件包和环境管理系统Anaconda的安装使用
2017/09/04 Python
python实现自主查询实时天气
2018/06/22 Python
Python实现定制自动化业务流量报表周报功能【XlsxWriter模块】
2019/03/11 Python
Python基于Tensor FLow的图像处理操作详解
2020/01/15 Python
解决pycharm安装第三方库失败的问题
2020/05/09 Python
Keras loss函数剖析
2020/07/06 Python
美体小铺美国官网:The Body Shop美国
2017/11/10 全球购物
政法学院毕业生求职信
2014/02/28 职场文书
4s店市场专员岗位职责
2014/04/09 职场文书
法学专业求职信
2014/07/15 职场文书
集结号观后感
2015/06/08 职场文书
创业方案:赚钱的烧烤店该怎样做?
2019/07/05 职场文书
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js