详解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的pandas框架操作Excel文件中的数据教程
Mar 31 Python
Python中is与==判断的区别
Mar 28 Python
python数据类型判断type与isinstance的区别实例解析
Oct 31 Python
pandas.dataframe中根据条件获取元素所在的位置方法(索引)
Jun 07 Python
Python中flatten( )函数及函数用法详解
Nov 02 Python
python合并已经存在的sheet数据到新sheet的方法
Dec 11 Python
详解Python字典的操作
Mar 04 Python
python ffmpeg任意提取视频帧的方法
Feb 21 Python
更新升级python和pip版本后不生效的问题解决
Apr 17 Python
Python3爬虫中pyspider的安装步骤
Jul 29 Python
Pycharm 如何一键加引号的方法步骤
Feb 05 Python
Python爬取科目四考试题库的方法实现
Mar 30 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
mysql 性能的检查和优化方法
2009/06/21 PHP
php SQL Injection with MySQL
2011/02/27 PHP
php中DOMElement操作xml文档实例演示
2013/03/26 PHP
ThinkPHP惯例配置文件详解
2014/07/14 PHP
php实现数组按指定KEY排序的方法
2015/03/30 PHP
php从数据库读取数据,并以json格式返回数据的方法
2018/08/21 PHP
wordpress自定义标签云与随机获取标签的方法详解
2019/03/22 PHP
PHP文件操作简单介绍及函数汇总
2020/12/11 PHP
下拉框select的绑定示例
2014/09/04 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
socket.io与pm2(cluster)集群搭配的解决方案
2017/06/02 Javascript
微信小程序之圆形进度条实现思路
2018/02/22 Javascript
详解react-redux插件入门
2018/04/19 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
JS实现520 表白简单代码
2018/05/21 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
2019/02/18 Javascript
8 个有用的JS技巧(推荐)
2019/07/03 Javascript
Angular6使用forRoot() 注册单一实例服务问题
2019/08/27 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
详解使用pymysql在python中对mysql的增删改查操作(综合)
2017/01/18 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
Python restful框架接口开发实现
2020/04/13 Python
详解pandas.DataFrame.plot() 画图函数
2020/06/14 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
css3 2D图片转动样式可以扩充到Js当中
2014/04/29 HTML / CSS
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
在线学习西班牙语、法语或其他语言:Babbel.com
2018/02/07 全球购物
意大利奢侈品多品牌集合店:TheDoubleF
2019/08/24 全球购物
儿科护理实习自我鉴定
2013/09/19 职场文书
外语专业毕业生个人的自荐信
2013/11/19 职场文书
英语专业学生的自我评价
2013/12/30 职场文书
婚礼证婚人演讲稿
2014/09/13 职场文书
《金色的草地》教学反思
2016/02/17 职场文书
Python-typing: 类型标注与支持 Any类型详解
2021/05/10 Python
python基础之函数的定义和调用
2021/10/24 Python
python神经网络 使用Keras构建RNN训练
2022/05/04 Python