详解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多线程学习资料
Dec 19 Python
一个超级简单的python web程序
Sep 11 Python
Python数据类型详解(二)列表
May 08 Python
numpy数组拼接简单示例
Dec 15 Python
Django 使用logging打印日志的实例
Apr 28 Python
利用pandas读取中文数据集的方法
Jul 25 Python
python输入整条数据分割存入数组的方法
Nov 13 Python
python实现烟花小程序
Jan 30 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
Mar 19 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
May 26 Python
Python selenium如何打包静态网页并下载
Aug 12 Python
通过代码实例了解Python3编程技巧
Oct 13 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 json转换成数组形式代码分享
2014/11/10 PHP
PHP合并静态文件详解
2014/11/14 PHP
浅析Yii2集成富文本编辑器redactor实例教程
2016/04/25 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
tagName的使用,留一笔
2006/06/26 Javascript
jQuery-ui中自动完成实现方法
2010/06/10 Javascript
JS简单实现文件上传实例代码(无需插件)
2013/11/15 Javascript
JS组件Bootstrap Table使用实例分享
2016/05/30 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
2016/06/20 Javascript
JavaScript中关键字 in 的使用方法详解
2016/10/17 Javascript
JS实现拖拽的方法分析
2016/12/20 Javascript
js获取地址栏中传递的参数(两种方法)
2017/02/08 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
轻松理解JavaScript之AJAX
2017/03/15 Javascript
Javascript中的getter和setter初识
2017/08/17 Javascript
微信小程序使用audio组件播放音乐功能示例【附源码下载】
2017/12/08 Javascript
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
bootstrap-table实现表头固定以及列固定的方法示例
2019/03/07 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
jQuery鼠标滑过横向时间轴样式(代码详解)
2019/11/01 jQuery
深入Python函数编程的一些特性
2015/04/13 Python
Pytorch mask_select 函数的用法详解
2020/02/18 Python
python如何写出表白程序
2020/06/01 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
猫途鹰英国网站:TripAdvisor英国(旅游社区和旅游评论)
2016/08/30 全球购物
哥德堡通行证:Gothenburg Pass
2019/12/09 全球购物
一道SQL存储过程面试题
2016/10/07 面试题
家长给小学生的评语
2014/01/30 职场文书
学生会招新策划书
2014/02/14 职场文书
《小猫刮胡子》教学反思
2014/02/21 职场文书
我为自己代言广告词
2014/03/18 职场文书
学雷锋树新风演讲稿
2014/05/10 职场文书
企业读书活动总结
2014/06/30 职场文书
装配出错检讨书
2014/09/23 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
ajax请求前端跨域问题原因及解决方案
2021/10/16 Javascript