详解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中的多线程实例教程
Aug 27 Python
跟老齐学Python之有容乃大的list(1)
Sep 14 Python
Python处理文本文件中控制字符的方法
Feb 07 Python
Python PyQt5实现的简易计算器功能示例
Aug 23 Python
Python中执行存储过程及获取存储过程返回值的方法
Oct 07 Python
人脸识别经典算法一 特征脸方法(Eigenface)
Mar 13 Python
解决已经安装requests,却依然提示No module named requests问题
May 18 Python
使用python将图片按标签分入不同文件夹的方法
Dec 08 Python
Python json转字典字符方法实例解析
Apr 13 Python
在Matplotlib图中插入LaTex公式实例
Apr 17 Python
python实现过滤敏感词
May 08 Python
python如何为list实现find方法
May 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
使用XHGui来测试PHP性能的教程
2015/07/03 PHP
汇总PHPmailer群发Gmail的常见问题
2016/02/24 PHP
详解PHP处理密码的几种方式
2016/11/30 PHP
PhpStorm本地断点调试的方法步骤
2018/05/21 PHP
PHP implode()函数用法讲解
2019/03/08 PHP
解决laravel session失效的问题
2019/10/14 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
学习ExtJS(一) 之基础前提
2009/10/07 Javascript
你可能不知道的JavaScript的new Function()方法
2014/04/17 Javascript
JavaScript中实现单体模式分享
2015/01/29 Javascript
Node.js中的process.nextTick使用实例
2015/06/25 Javascript
JS实现选择TextArea内文本的方法
2015/08/03 Javascript
AngularJS中实现用户访问的身份认证和表单验证功能
2016/04/21 Javascript
jQuery电话号码验证实例
2017/01/05 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
2017/01/23 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
详解ajax的data参数错误导致页面崩溃
2018/04/30 Javascript
vue resource发送请求的几种方式
2019/09/30 Javascript
原生JavaScript实现的无缝滚动功能详解
2020/01/17 Javascript
OpenLayers3实现地图鹰眼以及地图比例尺的添加
2020/09/25 Javascript
Python入门_学会创建并调用函数的方法
2017/05/16 Python
python 将列表中的字符串连接成一个长路径的方法
2018/10/23 Python
python实现ip地址查询经纬度定位详解
2019/08/30 Python
Python对接支付宝支付自实现功能
2019/10/10 Python
python 6种方法实现单例模式
2020/12/15 Python
HTML5跳转小程序wx-open-launch-weapp的示例代码
2020/07/16 HTML / CSS
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
建材业务员岗位职责
2013/12/08 职场文书
货车司机岗位职责
2014/03/18 职场文书
中学生运动会口号
2014/06/07 职场文书
2014年青年教师工作总结
2014/12/17 职场文书
老人节主持词
2015/07/04 职场文书
2016年村干部公开承诺书(公开承诺事项)
2016/03/25 职场文书
简单介绍 http请求响应参数、无连接无状态、MIME、状态码、端口、telnet、curl
2021/03/31 HTML / CSS
Python开发简易五子棋小游戏
2022/05/02 Python